Compare commits

...

89 Commits

Author SHA1 Message Date
Ajay
de314749b7 test old driver 2023-11-27 01:55:38 -05:00
Ajay
1e5bd80471 Add warning about extension storage being disable
Fixes issues with Tor and Mullvad browser
Fixes #1894
2023-11-27 01:04:06 -05:00
Ajay
d62d362f2e bump version 2023-11-27 00:40:17 -05:00
Ajay
2c67db44a0 Add button in dearrow prompt to quickly disable future prompts 2023-11-27 00:36:16 -05:00
Ajay
3ae0429043 Merge branch 'master' of https://github.com/ajayyy/SponsorBlock 2023-11-20 20:15:43 -05:00
Ajay
5ffbc9cabc Add support for userstyles in the popup
It takes userstyles from stylus or enhancer for YouTube and copies them to the popup in an iframe
2023-11-20 20:15:41 -05:00
Ajay Ramachandran
cbd96cb30b Merge pull request #1881 from ajayyy/dependabot/npm_and_yarn/babel/traverse-7.23.2
Bump @babel/traverse from 7.19.3 to 7.23.2
2023-11-09 18:45:39 -05:00
Ajay Ramachandran
3e5f391d3f Merge pull request #1905 from ajayyy/dependabot/npm_and_yarn/chromedriver-119.0.1
Bump chromedriver from 110.0.0 to 119.0.1
2023-11-09 17:29:32 -05:00
dependabot[bot]
c016107572 Bump chromedriver from 110.0.0 to 119.0.1
Bumps [chromedriver](https://github.com/giggio/node-chromedriver) from 110.0.0 to 119.0.1.
- [Commits](https://github.com/giggio/node-chromedriver/compare/110.0.0...119.0.1)

---
updated-dependencies:
- dependency-name: chromedriver
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-09 22:18:01 +00:00
Ajay
52bd85b850 bump version 2023-11-08 18:24:51 -05:00
Ajay
09e7c41479 update translations 2023-11-08 18:24:44 -05:00
Ajay
bdcb2d05c7 Make submission and skip notices slightly larger 2023-11-08 18:23:37 -05:00
Ajay
a522e3065c Fix regex being treated as a range 2023-11-08 18:22:41 -05:00
Ajay
72c62d0fa4 Deduplicate different quotes when comparing chapter names 2023-11-08 18:19:28 -05:00
Ajay
133ea360d7 Fix error when submitting with required segments 2023-11-08 18:13:38 -05:00
Ajay
e722ded58a Add dearrow promo based on title and remove old one
Also refactor requests out to seperate file
2023-11-08 16:07:59 -05:00
Ajay
6d37180d00 Add option to hide clutter in popup 2023-11-07 21:05:39 -05:00
Ajay
14d50b9e70 Add dearrow link to install page and add close button 2023-11-07 20:49:25 -05:00
Ajay
cfe314742d Rename Preview/Recap to Preview/Recap/Hook 2023-11-07 15:34:53 -05:00
Ajay
9a71e8bb8c Disable dearrow promotion 2023-11-06 19:33:05 -05:00
Ajay
dc2c7cc425 bump version 2023-11-02 14:34:51 -04:00
Ajay
7bf3237b72 update translations 2023-11-02 14:34:09 -04:00
Ajay
b48c854926 Another fix for flashing on Firefox when skipping some segments at the end of the video 2023-11-02 14:25:29 -04:00
Ajay
0bb7bef52c Merge branch 'master' of https://github.com/ajayyy/SponsorBlock 2023-11-01 16:08:53 -04:00
Ajay
4ffa019c68 Scroll down when new segment added to notice 2023-11-01 16:08:52 -04:00
Ajay
9c2007e0cf Rate limit saving times to make scrolling the edit box less laggy 2023-11-01 15:53:40 -04:00
Ajay Ramachandran
9176854d56 Merge pull request #1903 from ajayyy/ci/update_invidious_list
Update Invidious List
2023-10-31 21:02:16 -04:00
github-actions[bot]
65c72d38ea Update Invidious List 2023-11-01 00:19:59 +00:00
Ajay
6f54c8a731 Make highlight bigger on timeline when skip to highlight button hovered 2023-10-31 01:16:36 -04:00
Ajay
ca7eb50a82 bump version 2023-10-23 16:03:10 -04:00
Ajay
a7030fab9f update translations 2023-10-23 16:02:59 -04:00
Ajay
0bb3528cde Add minimum version of Firefox to manifest 2023-10-23 16:00:10 -04:00
Ajay
c8c141f5c9 Round end time when skipping on firefox if close
Fix #1883
2023-10-18 12:13:11 -04:00
dependabot[bot]
bd8326f95f Bump @babel/traverse from 7.19.3 to 7.23.2
Bumps [@babel/traverse](https://github.com/babel/babel/tree/HEAD/packages/babel-traverse) from 7.19.3 to 7.23.2.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.23.2/packages/babel-traverse)

---
updated-dependencies:
- dependency-name: "@babel/traverse"
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-18 09:42:36 +00:00
Ajay Ramachandran
88cfa023c9 Merge pull request #1880 from Choromanski/feature/remove-duplicate-id-sponsorTimePreviewButton
Renamed duplicate span id
2023-10-17 20:44:29 -04:00
Brian Choromanski
41a2fc2cb3 Assigned a new ID 'sponsorTimePreviewEndButton' to the newly added 'End' button 2023-10-17 17:06:41 -04:00
Ajay Ramachandran
0f0e404920 Merge pull request #1878 from Choromanski/feature/add-years-to-time-saved
Added years to time saved display
2023-10-15 21:36:05 -04:00
Brian Choromanski
f34fe5a032 Added years to time saved display 2023-10-15 21:23:49 -04:00
Ajay
e4c9afecbd bump version 2023-10-14 20:36:51 -04:00
Ajay
79e855a038 update translations 2023-10-14 20:36:45 -04:00
Ajay
09a3a4e6d4 Fix vote buttons in category pill missing not being centered 2023-10-14 20:32:48 -04:00
Ajay
e271f2cbcc Add gecko android to minimum version 2023-10-11 13:50:45 -04:00
Ajay
1cc4c18665 Fix video id not updating when changing videos on cytube and watchtogether 2023-10-08 20:22:45 -04:00
Ajay
e650b7183a bump version 2023-10-08 16:44:12 -04:00
Ajay
4eb097b422 update translations 2023-10-08 16:44:07 -04:00
Ajay
04a9f82bdc Rename hidden css class to sbhidden to fix compatibility with Piped
Fixes #1865
2023-10-08 16:38:40 -04:00
Ajay
39cfdc7b6c bump version 2023-10-01 13:57:51 -04:00
Ajay
a8701b02a1 update translations 2023-10-01 13:57:41 -04:00
Ajay
3f1ad528c3 Merge branch 'master' of https://github.com/ajayyy/SponsorBlock 2023-10-01 13:56:44 -04:00
Ajay
ae685baeef Fix tip ui broken for submissions 2023-10-01 13:56:34 -04:00
Ajay Ramachandran
d2ee67f3cf Merge pull request #1867 from ajayyy/ci/update_invidious_list
Update Invidious List
2023-09-30 20:57:53 -04:00
github-actions[bot]
d440a4d52a Update Invidious List 2023-10-01 00:21:32 +00:00
Ajay
7566b71ccd Properly hide dearrow button 2023-09-30 17:00:10 -04:00
Ajay
109b7ed5bc Don't show start button for highlight 2023-09-24 21:13:43 -04:00
Ajay
3eb853154f Remove unnecessary translation string 2023-09-24 19:01:41 -04:00
Ajay
ee3ce8aa46 Add seperate keybind for skip to highlight
Fixes #1187
2023-09-23 15:40:11 -04:00
Ajay
1557af5d2a update translations 2023-09-23 14:27:29 -04:00
Ajay
465e7065ca Update warning title 2023-09-23 13:46:12 -04:00
Ajay
a3f8419c49 update translations 2023-09-23 12:20:05 -04:00
Ajay
dde443ccec bump version 2023-09-23 12:18:32 -04:00
Ajay
01b1380b78 Update sponsorblock ui to tip 2023-09-23 12:17:46 -04:00
Ajay
c51b18465e Fix slightly different tv url format that appears on Firefox 2023-09-18 14:17:46 -04:00
Ajay
ad9888cf52 bump version 2023-09-17 17:31:36 -04:00
Ajay
7856791f90 update translations 2023-09-17 17:31:22 -04:00
Ajay
273ee63ec7 Prevent refreshes from triggering too often
Fixes #1838
2023-09-17 14:06:24 -04:00
Ajay
be36583aee Rename donate button 2023-09-17 13:11:52 -04:00
Ajay
433bbbf904 Remove popup css from content as iframes are used now
Fixes #1774
2023-09-17 12:46:25 -04:00
Ajay
6c2ee76198 Add start button to submission menu 2023-09-17 12:29:42 -04:00
Ajay
42f59898f3 Add end button for all segments 2023-09-17 12:12:00 -04:00
Ajay
8ab126f502 Highlight segment on hover 2023-09-17 12:06:33 -04:00
Ajay
4954abf9e3 Add extension icon default location on Firefox 2023-09-13 20:17:44 -04:00
Ajay
30a21d5ff5 Actually stop spacebar in chapters box from pausing video 2023-09-13 11:40:56 -04:00
Ajay
d1b2def47c bump version 2023-09-06 11:45:08 -04:00
Ajay Ramachandran
48cdabe2a5 Merge pull request #1534 from EthanBnntt/EthanBnntt-patch-1
Reduced execution time of hexToRgb function by ~70%
2023-09-05 01:28:23 -04:00
Ajay Ramachandran
bc2db0cf2c Merge branch 'master' into EthanBnntt-patch-1 2023-09-05 01:28:15 -04:00
Ajay Ramachandran
843ef37dcd Merge pull request #1814 from ajayyy/ci/update_invidious_list
Update Invidious List
2023-09-05 01:25:54 -04:00
Ajay
ed260a0667 Fix clicking a video from homepage on mobile YouTube
Fixes https://github.com/ajayyy/SponsorBlock/issues/1849
2023-09-05 01:19:50 -04:00
Ajay
2e131c2a95 Stop spacebar in chapters box from pausing video 2023-09-04 02:37:19 -04:00
Ajay
f5e884b6aa Merge branch 'master' of https://github.com/ajayyy/SponsorBlock 2023-09-03 21:29:02 -04:00
Ajay
a9929d0c93 Adjust dearrow message params 2023-09-03 21:29:00 -04:00
github-actions[bot]
3fb43d1c0e Update Invidious List 2023-09-01 00:19:28 +00:00
Ajay Ramachandran
a1b2855538 Merge pull request #1842 from ajayyy/ci/oss_attribution
Update OSS Attribution
2023-08-25 21:49:27 -04:00
github-actions[bot]
07236baed5 Update OSS Attribution 2023-08-26 01:30:48 +00:00
Ajay
f991435857 Switch back to upstream content-scripts-register-polyfill 2023-08-25 21:29:39 -04:00
Ajay
faa3259165 Fix invidious support on Safari for iOS 2023-08-25 20:22:58 -04:00
Ajay
c96bafb6f7 bump version 2023-08-25 18:39:52 -04:00
Ajay
9b7680f0e6 Fix invidious support on Safari 2023-08-25 16:38:50 -04:00
Ajay
16e01b7494 Fix comment 2023-08-25 16:34:08 -04:00
Bennett
edaed61612 Reduced execution time of hexToRgb function by ~70%
Coded to use less regex.
On average, "indexOf" performs better than "parseInt."
2022-10-13 14:48:17 -04:00
39 changed files with 745 additions and 400 deletions

View File

@@ -1 +1 @@
["www.youtubekids.com","inv.bp.projectsegfau.lt","inv.tux.pizza","inv.zzls.xyz","invidious.0011.lt","invidious.lunar.icu","invidious.privacydev.net","invidious.tiekoetter.com","iv.ggtyler.dev","iv.melmac.space","vid.priv.au","vid.puffyan.us","yewtu.be","yt.artemislena.eu"]
["www.youtubekids.com","anontube.lvkaszus.pl","inv.citw.lgbt","inv.in.projectsegfau.lt","inv.tux.pizza","inv.zzls.xyz","invidious.asir.dev","invidious.drgns.space","invidious.fdn.fr","invidious.flokinet.to","invidious.io.lol","invidious.lunar.icu","invidious.nerdvpn.de","invidious.no-logs.com","invidious.perennialte.ch","invidious.privacydev.net","invidious.private.coffee","invidious.projectsegfau.lt","invidious.protokolla.fi","invidious.slipfox.xyz","iv.datura.network","iv.ggtyler.dev","iv.melmac.space","iv.nboeck.de","onion.tube","vid.priv.au","vid.puffyan.us","yewtu.be","yt.artemislena.eu","yt.cdaut.de","yt.drgnz.club","yt.oelrichsgarcia.de"]

View File

@@ -1,7 +1,11 @@
{
"browser_specific_settings": {
"gecko": {
"id": "sponsorBlocker@ajay.app"
"id": "sponsorBlocker@ajay.app",
"strict_min_version": "48.0"
},
"gecko_android": {
"strict_min_version": "79.0"
}
},
"background": {
@@ -9,5 +13,8 @@
},
"permissions": [
"scripting"
]
],
"browser_action": {
"default_area": "navbar"
}
}

View File

@@ -1,7 +1,7 @@
{
"name": "__MSG_fullName__",
"short_name": "SponsorBlock",
"version": "5.4.17",
"version": "5.4.28",
"default_locale": "en",
"description": "__MSG_Description__",
"homepage_url": "https://sponsor.ajay.app",
@@ -17,9 +17,7 @@
],
"css": [
"content.css",
"shared.css",
"./libs/Source+Sans+Pro.css",
"popup.css"
"shared.css"
]
}],
"web_accessible_resources": [

View File

@@ -62,7 +62,7 @@
"webext-content-scripts": {
"ignore": false,
"name": "webext-content-scripts",
"version": "2.5.2",
"version": "2.5.5",
"authors": "Federico Brigante <me@fregante.com> (https://fregante.com)",
"url": "https://github.com/fregante/webext-content-scripts",
"license": "MIT",
@@ -80,7 +80,7 @@
"webext-polyfill-kinda": {
"ignore": false,
"name": "webext-polyfill-kinda",
"version": "1.0.0",
"version": "1.0.2",
"authors": "Federico Brigante <me@fregante.com> (https://fregante.com)",
"url": "https://github.com/fregante/webext-polyfill-kinda",
"license": "MIT",

367
package-lock.json generated
View File

@@ -79,12 +79,13 @@
}
},
"node_modules/@babel/code-frame": {
"version": "7.18.6",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz",
"integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==",
"version": "7.22.13",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz",
"integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==",
"dev": true,
"dependencies": {
"@babel/highlight": "^7.18.6"
"@babel/highlight": "^7.22.13",
"chalk": "^2.4.2"
},
"engines": {
"node": ">=6.9.0"
@@ -130,13 +131,14 @@
}
},
"node_modules/@babel/generator": {
"version": "7.19.3",
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.19.3.tgz",
"integrity": "sha512-fqVZnmp1ncvZU757UzDheKZpfPgatqY59XtW2/j/18H7u76akb8xqvjw82f+i2UKd/ksYsSick/BCLQUUtJ/qQ==",
"version": "7.23.0",
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.0.tgz",
"integrity": "sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==",
"dev": true,
"dependencies": {
"@babel/types": "^7.19.3",
"@babel/types": "^7.23.0",
"@jridgewell/gen-mapping": "^0.3.2",
"@jridgewell/trace-mapping": "^0.3.17",
"jsesc": "^2.5.1"
},
"engines": {
@@ -176,34 +178,34 @@
}
},
"node_modules/@babel/helper-environment-visitor": {
"version": "7.18.9",
"resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz",
"integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==",
"version": "7.22.20",
"resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz",
"integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==",
"dev": true,
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-function-name": {
"version": "7.19.0",
"resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz",
"integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==",
"version": "7.23.0",
"resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz",
"integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==",
"dev": true,
"dependencies": {
"@babel/template": "^7.18.10",
"@babel/types": "^7.19.0"
"@babel/template": "^7.22.15",
"@babel/types": "^7.23.0"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-hoist-variables": {
"version": "7.18.6",
"resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz",
"integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==",
"version": "7.22.5",
"resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz",
"integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==",
"dev": true,
"dependencies": {
"@babel/types": "^7.18.6"
"@babel/types": "^7.22.5"
},
"engines": {
"node": ">=6.9.0"
@@ -262,30 +264,30 @@
}
},
"node_modules/@babel/helper-split-export-declaration": {
"version": "7.18.6",
"resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz",
"integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==",
"version": "7.22.6",
"resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz",
"integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==",
"dev": true,
"dependencies": {
"@babel/types": "^7.18.6"
"@babel/types": "^7.22.5"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-string-parser": {
"version": "7.19.4",
"resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz",
"integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==",
"version": "7.22.5",
"resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz",
"integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==",
"dev": true,
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-validator-identifier": {
"version": "7.19.1",
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz",
"integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==",
"version": "7.22.20",
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz",
"integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==",
"dev": true,
"engines": {
"node": ">=6.9.0"
@@ -315,13 +317,13 @@
}
},
"node_modules/@babel/highlight": {
"version": "7.18.6",
"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz",
"integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==",
"version": "7.22.20",
"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz",
"integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==",
"dev": true,
"dependencies": {
"@babel/helper-validator-identifier": "^7.18.6",
"chalk": "^2.0.0",
"@babel/helper-validator-identifier": "^7.22.20",
"chalk": "^2.4.2",
"js-tokens": "^4.0.0"
},
"engines": {
@@ -329,9 +331,9 @@
}
},
"node_modules/@babel/parser": {
"version": "7.20.13",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.13.tgz",
"integrity": "sha512-gFDLKMfpiXCsjt4za2JA9oTMn70CeseCehb11kRZgvd7+F67Hih3OHOK24cRrWECJ/ljfPGac6ygXAs/C8kIvw==",
"version": "7.23.0",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz",
"integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==",
"dev": true,
"bin": {
"parser": "bin/babel-parser.js"
@@ -530,33 +532,33 @@
}
},
"node_modules/@babel/template": {
"version": "7.18.10",
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz",
"integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==",
"version": "7.22.15",
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz",
"integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==",
"dev": true,
"dependencies": {
"@babel/code-frame": "^7.18.6",
"@babel/parser": "^7.18.10",
"@babel/types": "^7.18.10"
"@babel/code-frame": "^7.22.13",
"@babel/parser": "^7.22.15",
"@babel/types": "^7.22.15"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/traverse": {
"version": "7.19.3",
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.19.3.tgz",
"integrity": "sha512-qh5yf6149zhq2sgIXmwjnsvmnNQC2iw70UFjp4olxucKrWd/dvlUsBI88VSLUsnMNF7/vnOiA+nk1+yLoCqROQ==",
"version": "7.23.2",
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz",
"integrity": "sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==",
"dev": true,
"dependencies": {
"@babel/code-frame": "^7.18.6",
"@babel/generator": "^7.19.3",
"@babel/helper-environment-visitor": "^7.18.9",
"@babel/helper-function-name": "^7.19.0",
"@babel/helper-hoist-variables": "^7.18.6",
"@babel/helper-split-export-declaration": "^7.18.6",
"@babel/parser": "^7.19.3",
"@babel/types": "^7.19.3",
"@babel/code-frame": "^7.22.13",
"@babel/generator": "^7.23.0",
"@babel/helper-environment-visitor": "^7.22.20",
"@babel/helper-function-name": "^7.23.0",
"@babel/helper-hoist-variables": "^7.22.5",
"@babel/helper-split-export-declaration": "^7.22.6",
"@babel/parser": "^7.23.0",
"@babel/types": "^7.23.0",
"debug": "^4.1.0",
"globals": "^11.1.0"
},
@@ -565,13 +567,13 @@
}
},
"node_modules/@babel/types": {
"version": "7.20.7",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.7.tgz",
"integrity": "sha512-69OnhBxSSgK0OzTJai4kyPDiKTIe3j+ctaHdIGVbRahTLAT7L3R9oeXHC2aVSuGYt3cVnoAMDmOCgJ2yaiLMvg==",
"version": "7.23.0",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.0.tgz",
"integrity": "sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==",
"dev": true,
"dependencies": {
"@babel/helper-string-parser": "^7.19.4",
"@babel/helper-validator-identifier": "^7.19.1",
"@babel/helper-string-parser": "^7.22.5",
"@babel/helper-validator-identifier": "^7.22.20",
"to-fast-properties": "^2.0.0"
},
"engines": {
@@ -1569,8 +1571,9 @@
}
},
"node_modules/@jridgewell/resolve-uri": {
"version": "3.0.4",
"integrity": "sha512-cz8HFjOFfUBtvN+NXYSFMHYRdxZMaEl0XypVrhzxBgadKIXhIkRd8aMeHhmF56Sl7SuS8OnUpQ73/k9LE4VnLg==",
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz",
"integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==",
"dev": true,
"engines": {
"node": ">=6.0.0"
@@ -1610,18 +1613,19 @@
}
},
"node_modules/@jridgewell/sourcemap-codec": {
"version": "1.4.10",
"integrity": "sha512-Ht8wIW5v165atIX1p+JvKR5ONzUyF4Ac8DZIQ5kZs9zrb6M8SJNXpx1zn04rn65VjBMygRoMXcyYwNK0fT7bEg==",
"version": "1.4.15",
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
"integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==",
"dev": true
},
"node_modules/@jridgewell/trace-mapping": {
"version": "0.3.15",
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.15.tgz",
"integrity": "sha512-oWZNOULl+UbhsgB51uuZzglikfIKSUBO/M9W2OfEjn7cmqoAiCgmv9lyACTUacZwBz0ITnJ2NqjU8Tx0DHL88g==",
"version": "0.3.20",
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz",
"integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==",
"dev": true,
"dependencies": {
"@jridgewell/resolve-uri": "^3.0.3",
"@jridgewell/sourcemap-codec": "^1.4.10"
"@jridgewell/resolve-uri": "^3.1.0",
"@jridgewell/sourcemap-codec": "^1.4.14"
}
},
"node_modules/@mdn/browser-compat-data": {
@@ -1739,9 +1743,9 @@
}
},
"node_modules/@testim/chrome-version": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/@testim/chrome-version/-/chrome-version-1.1.3.tgz",
"integrity": "sha512-g697J3WxV/Zytemz8aTuKjTGYtta9+02kva3C1xc7KXB8GdbfE1akGJIsZLyY/FSh2QrnE+fiB7vmWU3XNcb6A==",
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/@testim/chrome-version/-/chrome-version-1.1.4.tgz",
"integrity": "sha512-kIhULpw9TrGYnHp/8VfdcneIcxKnLixmADtukQRtJUmsVlMg0niMkwV0xZmi8hqa57xqilIHjWFA0GKvEjVU5g==",
"dev": true
},
"node_modules/@tootallnate/once": {
@@ -3195,9 +3199,9 @@
"dev": true
},
"node_modules/axios": {
"version": "1.2.6",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.2.6.tgz",
"integrity": "sha512-rC/7F08XxZwjMV4iuWv+JpD3E0Ksqg9nac4IIg6RwNuF0JTeWoCo/mBNG54+tNhhI11G3/VDRbdDQTs9hGp4pQ==",
"version": "1.6.1",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.6.1.tgz",
"integrity": "sha512-vfBmhDpKafglh0EldBEbVuoe7DyAavGSLWhuSm5ZSEKQnHhBf0xAAwybbNH1IkrJNGnS/VG4I5yxig1pCEXE4g==",
"dev": true,
"dependencies": {
"follow-redirects": "^1.15.0",
@@ -4089,9 +4093,9 @@
}
},
"node_modules/compare-versions": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-5.0.1.tgz",
"integrity": "sha512-v8Au3l0b+Nwkp4G142JcgJFh1/TUhdxut7wzD1Nq1dyp5oa3tXaqb03EXOAB6jS4gMlalkjAUPZBMiAfKUixHQ==",
"version": "5.0.3",
"resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-5.0.3.tgz",
"integrity": "sha512-4UZlZP8Z99MGEY+Ovg/uJxJuvoXuN4M6B3hKaiackiHrgzQFEe3diJi1mf1PNHbFujM7FvLrK2bpgIaImbtZ1A==",
"dev": true
},
"node_modules/concat-map": {
@@ -5979,9 +5983,9 @@
"dev": true
},
"node_modules/follow-redirects": {
"version": "1.15.2",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz",
"integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==",
"version": "1.15.3",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz",
"integrity": "sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==",
"dev": true,
"funding": [
{
@@ -10826,6 +10830,7 @@
},
"node_modules/proxy-from-env": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
"dev": true
},
@@ -12961,12 +12966,15 @@
}
},
"node_modules/webext-content-scripts": {
"version": "2.5.2",
"resolved": "https://registry.npmjs.org/webext-content-scripts/-/webext-content-scripts-2.5.2.tgz",
"integrity": "sha512-N1Xq/E8dx0lVAOyPquuo+2Vj9Fx1GoqCFo79lWeJHbemaBJ53N3BHBmbJJYsQ8FOP1xiwN4bPRQY2dpSjHAD3Q==",
"version": "2.5.5",
"resolved": "https://registry.npmjs.org/webext-content-scripts/-/webext-content-scripts-2.5.5.tgz",
"integrity": "sha512-CIq1LA/nHIXE43v8qlpqNPcbsSzGuQBkeykbqOWvKJ1Rx/q7zgdZsLgxwyoonWiQcJczslVmGWCfdBY04JwIyw==",
"dependencies": {
"webext-patterns": "^1.3.0",
"webext-polyfill-kinda": "^1.0.0"
"webext-polyfill-kinda": "^1.0.2"
},
"engines": {
"node": ">=16"
},
"funding": {
"url": "https://github.com/sponsors/fregante"
@@ -12995,9 +13003,9 @@
}
},
"node_modules/webext-polyfill-kinda": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/webext-polyfill-kinda/-/webext-polyfill-kinda-1.0.0.tgz",
"integrity": "sha512-Py/d3w/bC0KntuO60ePSWHsdrebZ3uYBLeFUjyPkDV3yTEQib0MRFvPh57t8XjImu4ylBoEAsFjzh/r22UtxMw==",
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/webext-polyfill-kinda/-/webext-polyfill-kinda-1.0.2.tgz",
"integrity": "sha512-rqQUKeBTOicej0tjDJWDQlOTnDcm9yYJTzgI+7rMdyYV4QHmYMRm+yjkcVgECkg/Wu9MboZ4lYeBPdp1Ep9WgQ==",
"funding": {
"url": "https://github.com/sponsors/fregante"
}
@@ -13586,12 +13594,13 @@
}
},
"@babel/code-frame": {
"version": "7.18.6",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz",
"integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==",
"version": "7.22.13",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz",
"integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==",
"dev": true,
"requires": {
"@babel/highlight": "^7.18.6"
"@babel/highlight": "^7.22.13",
"chalk": "^2.4.2"
}
},
"@babel/compat-data": {
@@ -13624,13 +13633,14 @@
}
},
"@babel/generator": {
"version": "7.19.3",
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.19.3.tgz",
"integrity": "sha512-fqVZnmp1ncvZU757UzDheKZpfPgatqY59XtW2/j/18H7u76akb8xqvjw82f+i2UKd/ksYsSick/BCLQUUtJ/qQ==",
"version": "7.23.0",
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.0.tgz",
"integrity": "sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==",
"dev": true,
"requires": {
"@babel/types": "^7.19.3",
"@babel/types": "^7.23.0",
"@jridgewell/gen-mapping": "^0.3.2",
"@jridgewell/trace-mapping": "^0.3.17",
"jsesc": "^2.5.1"
},
"dependencies": {
@@ -13660,28 +13670,28 @@
}
},
"@babel/helper-environment-visitor": {
"version": "7.18.9",
"resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz",
"integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==",
"version": "7.22.20",
"resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz",
"integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==",
"dev": true
},
"@babel/helper-function-name": {
"version": "7.19.0",
"resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz",
"integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==",
"version": "7.23.0",
"resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz",
"integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==",
"dev": true,
"requires": {
"@babel/template": "^7.18.10",
"@babel/types": "^7.19.0"
"@babel/template": "^7.22.15",
"@babel/types": "^7.23.0"
}
},
"@babel/helper-hoist-variables": {
"version": "7.18.6",
"resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz",
"integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==",
"version": "7.22.5",
"resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz",
"integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==",
"dev": true,
"requires": {
"@babel/types": "^7.18.6"
"@babel/types": "^7.22.5"
}
},
"@babel/helper-module-imports": {
@@ -13725,24 +13735,24 @@
}
},
"@babel/helper-split-export-declaration": {
"version": "7.18.6",
"resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz",
"integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==",
"version": "7.22.6",
"resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz",
"integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==",
"dev": true,
"requires": {
"@babel/types": "^7.18.6"
"@babel/types": "^7.22.5"
}
},
"@babel/helper-string-parser": {
"version": "7.19.4",
"resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz",
"integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==",
"version": "7.22.5",
"resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz",
"integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==",
"dev": true
},
"@babel/helper-validator-identifier": {
"version": "7.19.1",
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz",
"integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==",
"version": "7.22.20",
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz",
"integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==",
"dev": true
},
"@babel/helper-validator-option": {
@@ -13763,20 +13773,20 @@
}
},
"@babel/highlight": {
"version": "7.18.6",
"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz",
"integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==",
"version": "7.22.20",
"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz",
"integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==",
"dev": true,
"requires": {
"@babel/helper-validator-identifier": "^7.18.6",
"chalk": "^2.0.0",
"@babel/helper-validator-identifier": "^7.22.20",
"chalk": "^2.4.2",
"js-tokens": "^4.0.0"
}
},
"@babel/parser": {
"version": "7.20.13",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.13.tgz",
"integrity": "sha512-gFDLKMfpiXCsjt4za2JA9oTMn70CeseCehb11kRZgvd7+F67Hih3OHOK24cRrWECJ/ljfPGac6ygXAs/C8kIvw==",
"version": "7.23.0",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz",
"integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==",
"dev": true
},
"@babel/plugin-syntax-async-generators": {
@@ -13915,42 +13925,42 @@
}
},
"@babel/template": {
"version": "7.18.10",
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz",
"integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==",
"version": "7.22.15",
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz",
"integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.18.6",
"@babel/parser": "^7.18.10",
"@babel/types": "^7.18.10"
"@babel/code-frame": "^7.22.13",
"@babel/parser": "^7.22.15",
"@babel/types": "^7.22.15"
}
},
"@babel/traverse": {
"version": "7.19.3",
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.19.3.tgz",
"integrity": "sha512-qh5yf6149zhq2sgIXmwjnsvmnNQC2iw70UFjp4olxucKrWd/dvlUsBI88VSLUsnMNF7/vnOiA+nk1+yLoCqROQ==",
"version": "7.23.2",
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz",
"integrity": "sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.18.6",
"@babel/generator": "^7.19.3",
"@babel/helper-environment-visitor": "^7.18.9",
"@babel/helper-function-name": "^7.19.0",
"@babel/helper-hoist-variables": "^7.18.6",
"@babel/helper-split-export-declaration": "^7.18.6",
"@babel/parser": "^7.19.3",
"@babel/types": "^7.19.3",
"@babel/code-frame": "^7.22.13",
"@babel/generator": "^7.23.0",
"@babel/helper-environment-visitor": "^7.22.20",
"@babel/helper-function-name": "^7.23.0",
"@babel/helper-hoist-variables": "^7.22.5",
"@babel/helper-split-export-declaration": "^7.22.6",
"@babel/parser": "^7.23.0",
"@babel/types": "^7.23.0",
"debug": "^4.1.0",
"globals": "^11.1.0"
}
},
"@babel/types": {
"version": "7.20.7",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.7.tgz",
"integrity": "sha512-69OnhBxSSgK0OzTJai4kyPDiKTIe3j+ctaHdIGVbRahTLAT7L3R9oeXHC2aVSuGYt3cVnoAMDmOCgJ2yaiLMvg==",
"version": "7.23.0",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.0.tgz",
"integrity": "sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==",
"dev": true,
"requires": {
"@babel/helper-string-parser": "^7.19.4",
"@babel/helper-validator-identifier": "^7.19.1",
"@babel/helper-string-parser": "^7.22.5",
"@babel/helper-validator-identifier": "^7.22.20",
"to-fast-properties": "^2.0.0"
}
},
@@ -14691,8 +14701,9 @@
}
},
"@jridgewell/resolve-uri": {
"version": "3.0.4",
"integrity": "sha512-cz8HFjOFfUBtvN+NXYSFMHYRdxZMaEl0XypVrhzxBgadKIXhIkRd8aMeHhmF56Sl7SuS8OnUpQ73/k9LE4VnLg==",
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz",
"integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==",
"dev": true
},
"@jridgewell/set-array": {
@@ -14725,18 +14736,19 @@
}
},
"@jridgewell/sourcemap-codec": {
"version": "1.4.10",
"integrity": "sha512-Ht8wIW5v165atIX1p+JvKR5ONzUyF4Ac8DZIQ5kZs9zrb6M8SJNXpx1zn04rn65VjBMygRoMXcyYwNK0fT7bEg==",
"version": "1.4.15",
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
"integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==",
"dev": true
},
"@jridgewell/trace-mapping": {
"version": "0.3.15",
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.15.tgz",
"integrity": "sha512-oWZNOULl+UbhsgB51uuZzglikfIKSUBO/M9W2OfEjn7cmqoAiCgmv9lyACTUacZwBz0ITnJ2NqjU8Tx0DHL88g==",
"version": "0.3.20",
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz",
"integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==",
"dev": true,
"requires": {
"@jridgewell/resolve-uri": "^3.0.3",
"@jridgewell/sourcemap-codec": "^1.4.10"
"@jridgewell/resolve-uri": "^3.1.0",
"@jridgewell/sourcemap-codec": "^1.4.14"
}
},
"@mdn/browser-compat-data": {
@@ -14830,9 +14842,9 @@
}
},
"@testim/chrome-version": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/@testim/chrome-version/-/chrome-version-1.1.3.tgz",
"integrity": "sha512-g697J3WxV/Zytemz8aTuKjTGYtta9+02kva3C1xc7KXB8GdbfE1akGJIsZLyY/FSh2QrnE+fiB7vmWU3XNcb6A==",
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/@testim/chrome-version/-/chrome-version-1.1.4.tgz",
"integrity": "sha512-kIhULpw9TrGYnHp/8VfdcneIcxKnLixmADtukQRtJUmsVlMg0niMkwV0xZmi8hqa57xqilIHjWFA0GKvEjVU5g==",
"dev": true
},
"@tootallnate/once": {
@@ -15973,9 +15985,9 @@
"dev": true
},
"axios": {
"version": "1.2.6",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.2.6.tgz",
"integrity": "sha512-rC/7F08XxZwjMV4iuWv+JpD3E0Ksqg9nac4IIg6RwNuF0JTeWoCo/mBNG54+tNhhI11G3/VDRbdDQTs9hGp4pQ==",
"version": "1.6.1",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.6.1.tgz",
"integrity": "sha512-vfBmhDpKafglh0EldBEbVuoe7DyAavGSLWhuSm5ZSEKQnHhBf0xAAwybbNH1IkrJNGnS/VG4I5yxig1pCEXE4g==",
"dev": true,
"requires": {
"follow-redirects": "^1.15.0",
@@ -16609,9 +16621,9 @@
"dev": true
},
"compare-versions": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-5.0.1.tgz",
"integrity": "sha512-v8Au3l0b+Nwkp4G142JcgJFh1/TUhdxut7wzD1Nq1dyp5oa3tXaqb03EXOAB6jS4gMlalkjAUPZBMiAfKUixHQ==",
"version": "5.0.3",
"resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-5.0.3.tgz",
"integrity": "sha512-4UZlZP8Z99MGEY+Ovg/uJxJuvoXuN4M6B3hKaiackiHrgzQFEe3diJi1mf1PNHbFujM7FvLrK2bpgIaImbtZ1A==",
"dev": true
},
"concat-map": {
@@ -16739,7 +16751,7 @@
"resolved": "https://registry.npmjs.org/content-scripts-register-polyfill/-/content-scripts-register-polyfill-4.0.2.tgz",
"integrity": "sha512-8hDm+tu3BkxHZP7EUIIIo/495F6QNXF7cI9Lwr4PQaiohw2wWmi9k2SE4W4kNrAaLnFw6RZ2ev8EmrQb+sCoGQ==",
"requires": {
"webext-content-scripts": "^2.5.2",
"webext-content-scripts": "v2.5.5",
"webext-patterns": "^1.3.0",
"webext-polyfill-kinda": "^1.0.0"
}
@@ -17992,9 +18004,9 @@
"dev": true
},
"follow-redirects": {
"version": "1.15.2",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz",
"integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==",
"version": "1.15.3",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz",
"integrity": "sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==",
"dev": true
},
"for-each": {
@@ -21544,6 +21556,7 @@
},
"proxy-from-env": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
"dev": true
},
@@ -23096,12 +23109,12 @@
"dev": true
},
"webext-content-scripts": {
"version": "2.5.2",
"resolved": "https://registry.npmjs.org/webext-content-scripts/-/webext-content-scripts-2.5.2.tgz",
"integrity": "sha512-N1Xq/E8dx0lVAOyPquuo+2Vj9Fx1GoqCFo79lWeJHbemaBJ53N3BHBmbJJYsQ8FOP1xiwN4bPRQY2dpSjHAD3Q==",
"version": "2.5.5",
"resolved": "https://registry.npmjs.org/webext-content-scripts/-/webext-content-scripts-2.5.5.tgz",
"integrity": "sha512-CIq1LA/nHIXE43v8qlpqNPcbsSzGuQBkeykbqOWvKJ1Rx/q7zgdZsLgxwyoonWiQcJczslVmGWCfdBY04JwIyw==",
"requires": {
"webext-patterns": "^1.3.0",
"webext-polyfill-kinda": "^1.0.0"
"webext-polyfill-kinda": "^1.0.2"
}
},
"webext-patterns": {
@@ -23120,9 +23133,9 @@
}
},
"webext-polyfill-kinda": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/webext-polyfill-kinda/-/webext-polyfill-kinda-1.0.0.tgz",
"integrity": "sha512-Py/d3w/bC0KntuO60ePSWHsdrebZ3uYBLeFUjyPkDV3yTEQib0MRFvPh57t8XjImu4ylBoEAsFjzh/r22UtxMw=="
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/webext-polyfill-kinda/-/webext-polyfill-kinda-1.0.2.tgz",
"integrity": "sha512-rqQUKeBTOicej0tjDJWDQlOTnDcm9yYJTzgI+7rMdyYV4QHmYMRm+yjkcVgECkg/Wu9MboZ4lYeBPdp1Ep9WgQ=="
},
"webidl-conversions": {
"version": "7.0.0",

View File

@@ -8,6 +8,11 @@
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
"overrides": {
"content-scripts-register-polyfill": {
"webext-content-scripts": "v2.5.5"
}
},
"devDependencies": {
"@types/chrome": "^0.0.220",
"@types/firefox-webext-browser": "^111.0.0",

View File

@@ -7,7 +7,7 @@
--sb-dark-red-outline: rgb(130,0,0,0.9);
}
.hidden {
.sbhidden {
display: none;
}
@@ -49,7 +49,13 @@ div:hover > #previewbar.sbNotInvidious {
}
.previewbar.requiredSegment {
transform: scaleY(3)
transform: scaleY(3);
}
.previewbar.selectedSegment {
opacity: 1 !important;
z-index: 100;
transform: scaleY(1.5);
}
/* Make sure settings are upfront */
@@ -145,7 +151,7 @@ div:hover > .sponsorBlockChapterBar {
vertical-align: top;
}
.playerButton.hidden:not(.autoHiding) {
.playerButton.sbhidden:not(.autoHiding) {
display: none !important;
}
@@ -163,13 +169,13 @@ div:hover > .sponsorBlockChapterBar {
overflow: visible !important;
}
.autoHiding:not(.hidden) {
.autoHiding:not(.sbhidden) {
transform: translateX(0%) scale(1);
/* opacity is from YouTube page */
transition: transform 0.2s, width 0.2s, opacity .1s cubic-bezier(0.4,0.0,1,1) !important;
}
.autoHiding.hidden {
.autoHiding.sbhidden {
transform: translateX(100%) scale(0);
/* opacity is from YouTube page */
transition: transform 0.2s, width 0.2s, opacity .1s cubic-bezier(0.4,0.0,1,1) !important;
@@ -177,7 +183,7 @@ div:hover > .sponsorBlockChapterBar {
width: 0px !important;
}
.autoHiding.hidden.autoHideLeft {
.autoHiding.sbhidden.autoHideLeft {
transform: translateX(-100%) scale(0);
}
@@ -243,11 +249,6 @@ div:hover > .sponsorBlockChapterBar {
border-collapse: unset;
}
.sponsorSkipNoticeParent {
min-width: 350px;
max-width: 50%;
}
.sponsorSkipNotice {
width: 100%;
}
@@ -271,7 +272,7 @@ div:hover > .sponsorBlockChapterBar {
max-width: calc(100% - 50px);
}
.sponsorSkipNotice .hidden {
.sponsorSkipNotice .sbhidden {
display: none;
}
@@ -570,8 +571,8 @@ div:hover > .sponsorBlockChapterBar {
.sponsorTimeEditButton {
text-decoration: underline;
margin-left: 20px;
margin-right: 20px;
margin-left: 13px;
margin-right: 13px;
font-size: 13px;
@@ -690,7 +691,7 @@ input::-webkit-inner-spin-button {
color: white;
}
.skipButtonControlBarContainer.hidden {
.skipButtonControlBarContainer.sbhidden {
display: none !important;
}
@@ -741,6 +742,7 @@ input::-webkit-inner-spin-button {
color: white;
font-size: 12px;
z-index: 10000;
font-weight: normal;
}
.sponsorBlockTooltip a {
@@ -763,6 +765,12 @@ input::-webkit-inner-spin-button {
right: 50%;
}
.sponsorBlockTooltip.sbTriangle.sbTopTriangle::after {
bottom: 100%;
top: unset;
border-color: transparent transparent rgba(28, 28, 28, 0.7) transparent;
}
.sponsorBlockLockedColor {
color: #ffc83d !important;
}

View File

@@ -34,6 +34,20 @@
Come contribute, make some suggestions and help out on <a href="https://discord.gg/SponsorBlock">Discord</a> or on <a href="https://matrix.to/#/#sponsor:ajay.app?via=ajay.app&via=matrix.org&via=mozilla.org">Matrix</a>.
</p>
<a href="https://dearrow.ajay.app"
target="_blank"
id="dearrow-link"
class="dearrow-link hidden"
rel="noreferrer">
<img src="/icons/dearrow.svg"/>
<span id="dearrow-link-text">
</span>
<img src="/icons/close.png" class="close-button"/>
</a>
<p style="margin-bottom: 0; margin-top: 0" class="bigText center">__MSG_helpPageReviewOptions__</p>
<p class="smallText">

View File

@@ -322,4 +322,33 @@ svg {
cursor: default;
background-color: var(--disabled);
color: grey;
}
.dearrow-link {
display: flex;
align-items: center;
justify-content: center;
text-decoration: none;
font-size: 16px;
}
.dearrow-link img {
width: 35px;
padding: 10px
}
.dearrow-link .close-button {
opacity: 0;
width: 15px;
filter: invert(0.3);
transition: opacity 0.2s;
}
.dearrow-link:hover .close-button {
opacity: 1;
}
.hidden {
display: none;
}

View File

@@ -257,7 +257,7 @@ input[type='number'] {
opacity: 0;
}
.hidden {
.hidden, .sbhidden {
display: none !important;
}
@@ -717,4 +717,16 @@ svg {
.dearrow-link > img {
width: 40px;
margin-right: 4px;
}
.dearrow-link .close-button {
opacity: 0;
width: 15px;
filter: invert(0.3);
transition: opacity 0.2s;
margin-left: 10px;
}
.dearrow-link:hover .close-button {
opacity: 1;
}

View File

@@ -65,7 +65,7 @@
</div>
<div id="deArrowPromotion" class="promotion-container" class="hidden">
<div id="deArrowPromotion" class="promotion-container hidden">
<a class="dearrow-link"
href="https://dearrow.ajay.app"
target="_blank"
@@ -75,6 +75,8 @@
<span class="promotion-description">
__MSG_DeArrowPromotionMessage__
</span>
<img src="/icons/close.png" class="close-button"/>
</a>
</div>
@@ -357,6 +359,18 @@
<div class="small-description">__MSG_showTimeWithSkipsDescription__</div>
</div>
<div data-type="toggle" data-sync="cleanPopup" data-no-safari="true">
<div class="switch-container">
<label class="switch">
<input id="cleanPopup" type="checkbox" checked>
<span class="slider round"></span>
</label>
<label class="switch-label" for="cleanPopup">
__MSG_cleanPopup__
</label>
</div>
</div>
<div data-type="toggle" data-sync="darkMode">
<div class="switch-container">
<label class="switch">
@@ -414,6 +428,11 @@
<div class="inline"></div>
</div>
<div data-type="keybind-change" data-sync="skipToHighlightKeybind">
<label class="optionLabel">__MSG_skip_to_category__:</label>
<div class="inline"></div>
</div>
<div data-type="keybind-change" data-sync="startSponsorKeybind">
<label class="optionLabel">__MSG_setStartSponsorShortcut__:</label>
<div class="inline"></div>

View File

@@ -164,7 +164,7 @@ SOFTWARE.
******************************
webext-content-scripts
2.5.2 <https://github.com/fregante/webext-content-scripts>
2.5.5 <https://github.com/fregante/webext-content-scripts>
MIT License
Copyright (c) Federico Brigante <me@fregante.com> (https://fregante.com)
@@ -194,7 +194,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
******************************
webext-polyfill-kinda
1.0.0 <https://github.com/fregante/webext-polyfill-kinda>
1.0.2 <https://github.com/fregante/webext-polyfill-kinda>
MIT License
Copyright (c) Federico Brigante <me@fregante.com> (https://fregante.com)

View File

@@ -19,7 +19,7 @@ body {
font-weight: bold;
}
.hidden {
.hidden, .sbhidden {
display: none !important;
}

View File

@@ -27,7 +27,7 @@
position: relative;
}
#sponsorBlockPopupBody .hidden {
#sponsorBlockPopupBody .hidden, #sponsorBlockPopupBody .sbhidden {
display: none !important;
}
@@ -130,6 +130,7 @@
top: 5px;
right: 5px;
opacity: 0.5;
z-index: 1;
}
.sbCloseButton:hover {
@@ -260,19 +261,6 @@
text-align: right;
}
/*
* Buttons that appear under a segment on click
*/
.voteButton {
height: 20px;
padding: 0 5px;
cursor: pointer;
}
.voteButton:hover {
opacity: 0.8;
}
/*
* "Voted!" text that appears after voting on a segment
*/

View File

@@ -20,7 +20,7 @@
__MSG_betaServerWarning__
</div>
<header class="sbPopupLogo">
<header id="sbPopupLogo" class="sbPopupLogo">
<img src="icons/IconSponsorBlocker256px.png" alt="SponsorBlock" width="40" height="40" id="sponsorBlockPopupLogo">
<p class="u-mZ">SponsorBlock</p>
</header>
@@ -111,7 +111,7 @@
</div>
<!-- Your Work box -->
<div class="sbYourWorkBox">
<div id="sbYourWorkBox" class="sbYourWorkBox">
<h1 class="sbHeader" style="padding: 8px 15px;">
__MSG_yourWork__
</h1>
@@ -195,7 +195,7 @@
<a href="https://github.com/ajayyy/SponsorBlock" target="_blank" rel="noopener">GitHub</a>
<a href="https://discord.gg/SponsorBlock" target="_blank" rel="noopener">Discord</a>
<a href="https://matrix.to/#/#sponsor:ajay.app?via=ajay.app&via=matrix.org&via=mozilla.org" target="_blank" rel="noopener">Matrix</a>
<a href="https://sponsor.ajay.app/donate" target="_blank" rel="noopener" id="sbDonate">$</a>
<a href="https://sponsor.ajay.app/donate" target="_blank" rel="noopener" id="sbDonate">__MSG_Donate__</a>
</footer>
<button id="showNoticeAgain" style="display: none">__MSG_showNotice__</button>

View File

@@ -14,7 +14,7 @@
}
.sponsorSkipNoticeParent {
min-width: 350px;
min-width: 390px;
max-width: 50%;
}
@@ -36,7 +36,7 @@
max-width: calc(100% - 50px);
}
.sponsorSkipNotice .hidden {
.sponsorSkipNotice .sbhidden {
display: none;
}
@@ -216,4 +216,17 @@
display: flex;
align-items: center;
}
/*
* Buttons that appear under a segment on click
*/
.voteButton {
height: 20px;
padding: 0 5px;
cursor: pointer;
}
.voteButton:hover {
opacity: 0.8;
}

View File

@@ -121,7 +121,7 @@ chrome.runtime.onInstalled.addListener(function () {
const userID = Config.config.userID;
// If there is no userID, then it is the first install.
if (!userID){
if (!userID && !Config.local.alreadyInstalled){
//open up the install page
chrome.tabs.create({url: chrome.extension.getURL("/help/index.html")});
@@ -129,6 +129,7 @@ chrome.runtime.onInstalled.addListener(function () {
const newUserID = generateUserID();
//save this UUID
Config.config.userID = newUserID;
Config.local.alreadyInstalled = true;
// Don't show update notification
Config.config.categoryPillUpdate = true;
@@ -157,7 +158,7 @@ async function registerFirefoxContentScript(options: Registration) {
if ("scripting" in chrome && "getRegisteredContentScripts" in chrome.scripting) {
const existingRegistrations = await chromeP.scripting.getRegisteredContentScripts({
ids: [options.id]
});
}).catch(() => []);
if (existingRegistrations.length > 0
&& existingRegistrations[0].matches.every((match) => options.matches.includes(match))) {
@@ -200,7 +201,7 @@ async function unregisterFirefoxContentScript(id: string) {
ids: [id]
});
} catch (e) {
// Already registered
// Not registered yet
}
} else {
if (contentScriptRegistrations[id]) {

View File

@@ -44,7 +44,7 @@ class ChapterVoteComponent extends React.Component<ChapterVoteProps, ChapterVote
<>
{/* Upvote Button */}
<button id={"sponsorTimesDownvoteButtonsContainerUpvoteChapter"}
className={"playerButton sbPlayerUpvote ytp-button " + (!this.state.show ? "hidden" : "")}
className={"playerButton sbPlayerUpvote ytp-button " + (!this.state.show ? "sbhidden" : "")}
draggable="false"
title={chrome.i18n.getMessage("upvoteButtonInfo")}
onClick={(e) => this.vote(e, 1)}>
@@ -55,7 +55,7 @@ class ChapterVoteComponent extends React.Component<ChapterVoteProps, ChapterVote
{/* Downvote Button */}
<button id={"sponsorTimesDownvoteButtonsContainerDownvoteChapter"}
className={"playerButton sbPlayerDownvote ytp-button " + (!this.state.show ? "hidden" : "")}
className={"playerButton sbPlayerDownvote ytp-button " + (!this.state.show ? "sbhidden" : "")}
draggable="false"
title={chrome.i18n.getMessage("reportButtonInfo")}
onClick={(e) => {

View File

@@ -196,21 +196,21 @@ class NoticeComponent extends React.Component<NoticeProps, NoticeState> {
<span
id={"skipNoticeTimerText" + this.idSuffix}
key="skipNoticeTimerText"
className={this.state.countdownMode !== CountdownMode.Timer ? "hidden" : ""} >
className={this.state.countdownMode !== CountdownMode.Timer ? "sbhidden" : ""} >
{chrome.i18n.getMessage("NoticeTimeAfterSkip").replace("{seconds}", this.state.countdownTime.toString())}
</span>
),(
<img
id={"skipNoticeTimerPaused" + this.idSuffix}
key="skipNoticeTimerPaused"
className={this.state.countdownMode !== CountdownMode.Paused ? "hidden" : ""}
className={this.state.countdownMode !== CountdownMode.Paused ? "sbhidden" : ""}
src={chrome.runtime.getURL("icons/pause.svg")}
alt={chrome.i18n.getMessage("paused")} />
),(
<img
id={"skipNoticeTimerStopped" + this.idSuffix}
key="skipNoticeTimerStopped"
className={this.state.countdownMode !== CountdownMode.Stopped ? "hidden" : ""}
className={this.state.countdownMode !== CountdownMode.Stopped ? "sbhidden" : ""}
src={chrome.runtime.getURL("icons/stop.svg")}
alt={chrome.i18n.getMessage("manualPaused")} />
)];

View File

@@ -2,14 +2,12 @@ import * as React from "react";
import * as CompileConfig from "../../config.json";
import Config from "../config";
import { ActionType, Category, ChannelIDStatus, ContentContainer, SponsorTime } from "../types";
import Utils from "../utils";
import SubmissionNoticeComponent from "./SubmissionNoticeComponent";
import { RectangleTooltip } from "../render/RectangleTooltip";
import SelectorComponent, { SelectorOption } from "./SelectorComponent";
import { DEFAULT_CATEGORY } from "../utils/categoryUtils";
import { getFormattedTime, getFormattedTimeToSeconds } from "../../maze-utils/src/formating";
const utils = new Utils();
import { asyncRequestToServer } from "../utils/requests";
export interface SponsorTimeEditProps {
index: number;
@@ -128,6 +126,14 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo
style={timeDisplayStyle}
className="sponsorTimeDisplay">
{sponsorTime.actionType !== ActionType.Poi ? (
<span id={"startButton" + this.idSuffix}
className="sponsorNowButton"
onClick={() => this.setTimeTo(0, 0)}>
{chrome.i18n.getMessage("bracketStart")}
</span>
): ""}
<span id={"nowButton0" + this.idSuffix}
className="sponsorNowButton"
onClick={() => this.setTimeToNow(0)}>
@@ -138,6 +144,8 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo
type="text"
style={{color: "inherit", backgroundColor: "inherit"}}
value={this.state.sponsorTimeEdits[0]}
onKeyDown={(e) => e.stopPropagation()}
onKeyUp={(e) => e.stopPropagation()}
onChange={(e) => this.handleOnChange(0, e, sponsorTime, e.target.value)}
onWheel={(e) => this.changeTimesWhenScrolling(0, e, sponsorTime)}>
</input>
@@ -153,6 +161,8 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo
type="text"
style={{color: "inherit", backgroundColor: "inherit"}}
value={this.state.sponsorTimeEdits[1]}
onKeyDown={(e) => e.stopPropagation()}
onKeyUp={(e) => e.stopPropagation()}
onChange={(e) => this.handleOnChange(1, e, sponsorTime, e.target.value)}
onWheel={(e) => this.changeTimesWhenScrolling(1, e, sponsorTime)}>
</input>
@@ -238,6 +248,8 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo
ref={this.descriptionOptionRef}
type="text"
value={this.state.description}
onKeyDown={(e) => e.stopPropagation()}
onKeyUp={(e) => e.stopPropagation()}
onContextMenu={(e) => e.stopPropagation()}
onChange={(e) => this.descriptionUpdate(e.target.value)}
onFocus={() => this.setState({chapterNameSelectorOpen: true})}>
@@ -282,11 +294,10 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo
</span>
): ""}
{(!isNaN(segment[1]) && ![ActionType.Poi, ActionType.Full].includes(sponsorTime.actionType))
&& sponsorTime.actionType === ActionType.Chapter ? (
<span id={"sponsorTimePreviewButton" + this.idSuffix}
{(!isNaN(segment[1]) && ![ActionType.Poi, ActionType.Full].includes(sponsorTime.actionType)) ? (
<span id={"sponsorTimePreviewEndButton" + this.idSuffix}
className="sponsorTimeEditButton"
onClick={(e) => this.previewTime(e.ctrlKey, e.shiftKey)}>
onClick={(e) => this.previewTime(e.ctrlKey, e.shiftKey, true)}>
{chrome.i18n.getMessage("End")}
</span>
): ""}
@@ -577,7 +588,24 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo
getFormattedTime(sponsorTime.segment[1], true)];
}
lastEditTime = 0;
editTimeTimeout: NodeJS.Timeout | null = null;
saveEditTimes(): void {
// Rate limit edits
const timeSinceLastEdit = Date.now() - this.lastEditTime;
if (timeSinceLastEdit < 200) {
if (!this.editTimeTimeout) {
this.editTimeTimeout = setTimeout(() => {
this.saveEditTimes();
}, timeSinceLastEdit)
}
return;
}
this.lastEditTime = Date.now();
this.editTimeTimeout = null;
const sponsorTimesSubmitting = this.props.contentContainer().sponsorTimesSubmitting;
const category = this.categoryOptionRef.current.value as Category
@@ -624,7 +652,7 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo
: CompileConfig.categorySupport[category]?.[0] ?? ActionType.Skip
}
previewTime(ctrlPressed = false, shiftPressed = false): void {
previewTime(ctrlPressed = false, shiftPressed = false, skipToEndTime = false): void {
const sponsorTimes = this.props.contentContainer().sponsorTimesSubmitting;
const index = this.props.index;
let seekTime = 2;
@@ -633,13 +661,11 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo
const startTime = sponsorTimes[index].segment[0];
const endTime = sponsorTimes[index].segment[1];
const isChapter = sponsorTimes[index].actionType === ActionType.Chapter;
// If segment starts at 0:00, start playback at the end of the segment
const skipToEndTime = startTime === 0 || isChapter;
const skipTime = skipToEndTime ? endTime : (startTime - (seekTime * this.props.contentContainer().v.playbackRate));
const skipTime = (startTime === 0 || skipToEndTime) ? endTime : (startTime - (seekTime * this.props.contentContainer().v.playbackRate));
this.props.contentContainer().previewTime(skipTime, !isChapter);
this.props.contentContainer().previewTime(skipTime, !skipToEndTime);
}
inspectTime(): void {
@@ -699,7 +725,7 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo
if (this.props.contentContainer().channelIDInfo.status !== ChannelIDStatus.Found) return;
this.fetchingSuggestions = true;
const result = await utils.asyncRequestToServer("GET", "/api/chapterNames", {
const result = await asyncRequestToServer("GET", "/api/chapterNames", {
description,
channelID: this.props.contentContainer().channelIDInfo.id
});

View File

@@ -38,6 +38,8 @@ class SubmissionNoticeComponent extends React.Component<SubmissionNoticeProps, S
guidelinesReminder: GenericNotice;
lastSegmentCount: number;
constructor(props: SubmissionNoticeProps) {
super(props);
this.noticeRef = React.createRef();
@@ -47,12 +49,14 @@ class SubmissionNoticeComponent extends React.Component<SubmissionNoticeProps, S
const noticeTitle = chrome.i18n.getMessage("confirmNoticeTitle");
this.lastSegmentCount = this.props.contentContainer().sponsorTimesSubmitting.length;
// Setup state
this.state = {
noticeTitle,
messages: [],
idSuffix: "SubmissionNotice"
}
};
}
componentDidMount(): void {
@@ -73,6 +77,18 @@ class SubmissionNoticeComponent extends React.Component<SubmissionNoticeProps, S
}
}
componentDidUpdate() {
const currentSegmentCount = this.props.contentContainer().sponsorTimesSubmitting.length;
if (currentSegmentCount > this.lastSegmentCount) {
this.lastSegmentCount = currentSegmentCount;
const scrollElement = this.noticeRef.current.getElement().current.querySelector("#sponsorSkipNoticeMiddleRowSubmissionNotice");
scrollElement.scrollTo({
top: scrollElement.scrollHeight + 1000
});
}
}
render(): React.ReactElement {
const sortButton =
<img id={"sponsorSkipSortButton" + this.state.idSuffix}

View File

@@ -75,7 +75,10 @@ interface SBConfig {
allowScrollingToEdit: boolean;
deArrowInstalled: boolean;
showDeArrowPromotion: boolean;
showDeArrowInSettings: boolean;
shownDeArrowPromotion: boolean;
showZoomToFillError2: boolean;
cleanPopup: boolean;
// Used to cache calculated text color info
categoryPillColors: {
@@ -86,6 +89,7 @@ interface SBConfig {
};
skipKeybind: Keybind;
skipToHighlightKeybind: Keybind;
startSponsorKeybind: Keybind;
submitKeybind: Keybind;
nextChapterKeybind: Keybind;
@@ -133,6 +137,9 @@ interface SBStorage {
/* VideoID prefixes to UUID prefixes */
downvotedSegments: Record<VideoID & HashedValue, VideoDownvotes>;
navigationApiAvailable: boolean;
// Used when sync storage disbaled
alreadyInstalled: boolean;
}
class ConfigClass extends ProtoConfig<SBConfig, SBStorage> {
@@ -316,7 +323,10 @@ const syncDefaults = {
allowScrollingToEdit: true,
deArrowInstalled: false,
showDeArrowPromotion: true,
showDeArrowInSettings: true,
shownDeArrowPromotion: false,
showZoomToFillError2: true,
cleanPopup: false,
categoryPillColors: {},
@@ -328,6 +338,7 @@ const syncDefaults = {
* TODO: Find a way to skip having to update these checks. Maybe storing keybinds in a Map?
*/
skipKeybind: { key: "Enter" },
skipToHighlightKeybind: { key: "Enter", ctrl: true },
startSponsorKeybind: { key: ";" },
submitKeybind: { key: "'" },
nextChapterKeybind: { key: "ArrowRight", ctrl: true },
@@ -448,7 +459,8 @@ const syncDefaults = {
const localDefaults = {
downvotedSegments: {},
navigationApiAvailable: null
navigationApiAvailable: null,
alreadyInstalled: false
};
const Config = new ConfigClass(syncDefaults, localDefaults, migrateOldSyncFormats);

View File

@@ -28,7 +28,7 @@ import { getControls, getExistingChapters, getHashParams, isPlayingPlaylist, isV
import { CategoryPill } from "./render/CategoryPill";
import { AnimationUtils } from "./utils/animationUtils";
import { GenericUtils } from "./utils/genericUtils";
import { logDebug } from "./utils/logger";
import { logDebug, logWarn } from "./utils/logger";
import { importTimes } from "./utils/exporter";
import { ChapterVote } from "./render/ChapterVote";
import { openWarningDialog } from "./utils/warnings";
@@ -36,17 +36,17 @@ import { isFirefoxOrSafari, waitFor } from "../maze-utils/src";
import { getErrorMessage, getFormattedTime } from "../maze-utils/src/formating";
import { getChannelIDInfo, getVideo, getIsAdPlaying, getIsLivePremiere, setIsAdPlaying, checkVideoIDChange, getVideoID, getYouTubeVideoID, setupVideoModule, checkIfNewVideoID, isOnInvidious, isOnMobileYouTube } from "../maze-utils/src/video";
import { Keybind, StorageChangesObject, isSafari, keybindEquals } from "../maze-utils/src/config";
import { findValidElement, waitForElement } from "../maze-utils/src/dom"
import { findValidElement } from "../maze-utils/src/dom"
import { getHash, HashedValue } from "../maze-utils/src/hash";
import { generateUserID } from "../maze-utils/src/setup";
import { updateAll } from "../maze-utils/src/thumbnailManagement";
import { setupThumbnailListener } from "./utils/thumbnails";
import * as documentScript from "../dist/js/document.js";
import { Tooltip } from "./render/Tooltip";
import { isDeArrowInstalled } from "./utils/crossExtension";
import { runCompatibilityChecks } from "./utils/compatibility";
import { cleanPage } from "./utils/pageCleaner";
import { addCleanupListener } from "../maze-utils/src/cleanup";
import { hideDeArrowPromotion, tryShowingDeArrowPromotion } from "./dearrowPromotion";
import { asyncRequestToServer } from "./utils/requests";
cleanPage();
@@ -57,47 +57,12 @@ utils.wait(() => Config.isReady(), 5000, 10).then(() => {
addCSS();
setCategoryColorCSSVariables();
// DeArrow promotion
setTimeout(async () => {
if (document.URL === "https://www.youtube.com/"
&& Config.config.showDeArrowPromotion
&& Config.config.showUpsells
&& Config.config.showNewFeaturePopups
&& (Config.config.skipCount > 100 || !Config.config.trackViewCount)
&& Math.random() < 0.05) {
if (!await isDeArrowInstalled()) {
const element = await waitForElement("#contents") as HTMLElement;
if (element) {
Config.config.showDeArrowPromotion = false;
new Tooltip({
text: chrome.i18n.getMessage("DeArrowPromotionMessage2"),
linkOnClick: () => window.open("https://dearrow.ajay.app"),
referenceNode: element,
prependElement: element.firstElementChild as HTMLElement,
timeout: 15000,
positionRealtive: false,
containerAbsolute: true,
bottomOffset: "inherit",
topOffset: "-82px",
leftOffset: "0",
rightOffset: "0",
displayTriangle: false,
center: true,
opacity: 1
});
}
} else {
Config.config.showDeArrowPromotion = false;
}
}
}, 5000);
runCompatibilityChecks();
});
const skipBuffer = 0.003;
// If this close to the end, skip to the end
const endTimeSkipBuffer = 0.5;
//was sponsor data found when doing SponsorsLookup
let sponsorDataFound = false;
@@ -110,6 +75,7 @@ const skipNotices: SkipNotice[] = [];
let activeSkipKeybindElement: ToggleSkippable = null;
let retryFetchTimeout: NodeJS.Timeout = null;
let shownSegmentFailedToFetchWarning = false;
let selectedSegment: SegmentUUID | null = null;
// JSON video info
let videoInfo: VideoInfo = null;
@@ -300,6 +266,9 @@ function messageListener(request: Message, sender: unknown, sendResponse: (respo
case "reskip":
reskipSponsorTime(sponsorTimes.find((segment) => segment.UUID === request.UUID), true);
break;
case "selectSegment":
selectSegment(request.UUID);
break;
case "submitVote":
vote(request.type, request.UUID).then((response) => sendResponse(response));
return true;
@@ -434,6 +403,8 @@ function resetValues() {
for (let i = 0; i < skipNotices.length; i++) {
skipNotices.pop()?.close();
}
hideDeArrowPromotion();
}
function videoIDChange(): void {
@@ -474,6 +445,8 @@ function videoIDChange(): void {
// Clear unsubmitted segments from the previous video
sponsorTimesSubmitting = [];
updateSponsorTimesSubmitting();
tryShowingDeArrowPromotion().catch(logWarn);
}
function handleMobileControlsMutations(): void {
@@ -618,7 +591,8 @@ async function startSponsorSchedule(includeIntersectingSegments = false, current
updateActiveSegment(currentTime);
if (getVideo().paused) return;
if (getVideo().paused
|| (getVideo().currentTime >= getVideo().duration - 0.01 && getVideo().duration > 1)) return;
const skipInfo = getNextSkipIndex(currentTime, includeIntersectingSegments, includeNonIntersectingSegments);
const currentSkip = skipInfo.array[skipInfo.index];
@@ -697,8 +671,12 @@ async function startSponsorSchedule(includeIntersectingSegments = false, current
forcedSkipTime = skipTime[0] + 0.001;
} else {
forcedSkipTime = skipTime[1];
forcedIncludeIntersectingSegments = true;
forcedIncludeNonIntersectingSegments = false;
// Only if not at the end of the video
if (Math.abs(skipTime[1] - getVideo().duration) > endTimeSkipBuffer) {
forcedIncludeIntersectingSegments = true;
}
}
} else {
forcedSkipTime = forceVideoTime + 0.001;
@@ -1066,6 +1044,7 @@ function setupSkipButtonControlBar() {
openNotice: true,
forceAutoSkip: true
}),
selectSegment,
onMobileYouTube: isOnMobileYouTube()
});
}
@@ -1100,7 +1079,7 @@ async function sponsorsLookup(keepOldSubmissions = true) {
if (hashParams.requiredSegment) extraRequestData.requiredSegment = hashParams.requiredSegment;
const hashPrefix = (await getHash(getVideoID(), 1)).slice(0, 4) as VideoID & HashedValue;
const response = await utils.asyncRequestToServer('GET', "/api/skipSegments/" + hashPrefix, {
const response = await asyncRequestToServer('GET', "/api/skipSegments/" + hashPrefix, {
categories,
actionTypes: getEnabledActionTypes(),
userAgent: `${chrome.runtime.id}`,
@@ -1240,7 +1219,7 @@ function getEnabledActionTypes(forceFullVideo = false): ActionType[] {
async function lockedCategoriesLookup(): Promise<void> {
const hashPrefix = (await getHash(getVideoID(), 1)).slice(0, 4);
const response = await utils.asyncRequestToServer("GET", "/api/lockCategories/" + hashPrefix);
const response = await asyncRequestToServer("GET", "/api/lockCategories/" + hashPrefix);
if (response.ok) {
try {
@@ -1344,6 +1323,11 @@ function updatePreviewBarPositionMobile(parent: HTMLElement) {
}
}
function selectSegment(UUID: SegmentUUID): void {
selectedSegment = UUID;
updatePreviewBar();
}
function updatePreviewBar(): void {
if (previewBar === null) return;
@@ -1369,7 +1353,8 @@ function updatePreviewBar(): void {
showLarger: segment.actionType === ActionType.Poi,
description: segment.description,
source: segment.source,
requiredSegment: requiredSegment && (segment.UUID === requiredSegment || segment.UUID.startsWith(requiredSegment))
requiredSegment: requiredSegment && (segment.UUID === requiredSegment || segment.UUID?.startsWith(requiredSegment)),
selectedSegment: selectedSegment && segment.UUID === selectedSegment
});
});
}
@@ -1628,7 +1613,7 @@ function sendTelemetryAndCount(skippingSegments: SponsorTime[], secondsSkipped:
counted = true;
}
if (fullSkip) utils.asyncRequestToServer("POST", "/api/viewedVideoSponsorTime?UUID=" + segment.UUID);
if (fullSkip) asyncRequestToServer("POST", "/api/viewedVideoSponsorTime?UUID=" + segment.UUID);
}
}
}
@@ -1654,6 +1639,9 @@ function skipToTime({v, skipTime, skippingSegments, openNotice, forceAutoSkip, u
// MacOS will loop otherwise #1027
// Sometimes playlists loop too #1804
v.currentTime = v.duration - 0.001;
} else if (v.duration > 1 && Math.abs(skipTime[1] - v.duration) < endTimeSkipBuffer
&& isFirefoxOrSafari() && !isSafari()) {
v.currentTime = v.duration;
} else {
if (inMuteSegment(skipTime[1], true)) {
// Make sure not to mute if skipping into a mute segment
@@ -2028,7 +2016,6 @@ function openInfoMenu() {
//hide info button
if (playerButtons.info) playerButtons.info.button.style.display = "none";
const popup = document.createElement("div");
popup.id = "sponsorBlockPopupContainer";
@@ -2036,7 +2023,37 @@ function openInfoMenu() {
frame.width = "374";
frame.height = "500";
frame.style.borderRadius = "12px";
frame.addEventListener("load", () => frame.contentWindow.postMessage("", "*"));
frame.addEventListener("load", async () => {
frame.contentWindow.postMessage("", "*");
// To support userstyles applying to the popup
const stylusStyle = document.querySelector(".stylus");
if (stylusStyle) {
frame.contentWindow.postMessage({
type: "style",
css: stylusStyle.textContent
}, "*");
}
const enhancerStyle = document.getElementById("efyt-theme");
if (enhancerStyle) {
const enhancerStyleVariables = document.getElementById("efyt-theme-variables");
if (enhancerStyleVariables) {
const enhancerCss = await fetch(enhancerStyle.getAttribute("href")).then((response) => response.text());
const enhancerVariablesCss = await fetch(enhancerStyleVariables.getAttribute("href")).then((response) => response.text());
if (enhancerCss && enhancerVariablesCss) {
frame.contentWindow.postMessage({
type: "style",
// Image needs needs to reference the full url now
css: enhancerCss.replace("./images/youtube-deep-dark/IconSponsorBlocker256px.png",
"https://raw.githubusercontent.com/RaitaroH/YouTube-DeepDark/master/YT_Images/IconSponsorBlocker256px.png")
+ enhancerVariablesCss
}, "*");
}
}
}
});
frame.src = chrome.extension.getURL("popup.html");
popup.appendChild(frame);
@@ -2121,7 +2138,7 @@ async function vote(type: number, UUID: SegmentUUID, category?: Category, skipNo
//success (treat rate limits as a success)
skipNotice.afterVote.bind(skipNotice)(utils.getSponsorTimeFromUUID(sponsorTimes, UUID), type, category);
} else if (response.successType == -1) {
if (response.statusCode === 403 && response.responseText.startsWith("Vote rejected due to a warning from a moderator.")) {
if (response.statusCode === 403 && response.responseText.startsWith("Vote rejected due to a tip from a moderator.")) {
openWarningDialog(skipNoticeContentContainer);
} else {
skipNotice.setNoticeInfoMessage.bind(skipNotice)(getErrorMessage(response.statusCode, response.responseText))
@@ -2261,7 +2278,7 @@ async function sendSubmitMessage() {
}
}
const response = await utils.asyncRequestToServer("POST", "/api/skipSegments", {
const response = await asyncRequestToServer("POST", "/api/skipSegments", {
videoID: getVideoID(),
userID: Config.config.userID,
segments: sponsorTimesSubmitting,
@@ -2311,7 +2328,7 @@ async function sendSubmitMessage() {
playerButtons.submit.button.style.animation = "unset";
playerButtons.submit.image.src = chrome.extension.getURL("icons/PlayerUploadFailedIconSponsorBlocker.svg");
if (response.status === 403 && response.responseText.startsWith("Submission rejected due to a warning from a moderator.")) {
if (response.status === 403 && response.responseText.startsWith("Submission rejected due to a tip from a moderator.")) {
openWarningDialog(skipNoticeContentContainer);
} else {
alert(getErrorMessage(response.status, response.responseText));
@@ -2426,14 +2443,23 @@ function hotkeyListener(e: KeyboardEvent): void {
};
const skipKey = Config.config.skipKeybind;
const skipToHighlightKey = Config.config.skipToHighlightKeybind;
const startSponsorKey = Config.config.startSponsorKeybind;
const submitKey = Config.config.submitKeybind;
const nextChapterKey = Config.config.nextChapterKeybind;
const previousChapterKey = Config.config.previousChapterKeybind;
if (keybindEquals(key, skipKey)) {
if (activeSkipKeybindElement)
if (activeSkipKeybindElement) {
activeSkipKeybindElement.toggleSkip.call(activeSkipKeybindElement);
}
return;
} else if (keybindEquals(key, skipToHighlightKey)) {
if (skipButtonControlBar) {
skipButtonControlBar.toggleSkip.call(skipButtonControlBar);
}
return;
} else if (keybindEquals(key, startSponsorKey)) {
startOrEndTimingNewSegment();

72
src/dearrowPromotion.ts Normal file
View File

@@ -0,0 +1,72 @@
import { waitFor } from "../maze-utils/src";
import { getYouTubeTitleNode } from "../maze-utils/src/elements";
import { getHash } from "../maze-utils/src/hash";
import { getVideoID, isOnInvidious, isOnMobileYouTube } from "../maze-utils/src/video";
import Config from "./config";
import { Tooltip } from "./render/Tooltip";
import { isDeArrowInstalled } from "./utils/crossExtension";
import { isVisible } from "./utils/pageUtils";
import { asyncRequestToServer } from "./utils/requests";
let tooltip: Tooltip = null;
export async function tryShowingDeArrowPromotion() {
if (Config.config.showDeArrowPromotion
&& !isOnMobileYouTube()
&& !isOnInvidious()
&& document.URL.includes("watch")
&& Config.config.showUpsells
&& Config.config.showNewFeaturePopups
&& (Config.config.skipCount > 30 || !Config.config.trackViewCount)) {
if (!await isDeArrowInstalled()) {
try {
const element = await waitFor(() => getYouTubeTitleNode(), 5000, 500, (e) => isVisible(e)) as HTMLElement;
if (element && element.innerText && badTitle(element.innerText)) {
const hashPrefix = (await getHash(getVideoID(), 1)).slice(0, 4);
const deArrowData = await asyncRequestToServer("GET", "/api/branding/" + hashPrefix);
if (!deArrowData.ok) return;
const deArrowDataJson = JSON.parse(deArrowData.responseText);
const title = deArrowDataJson?.[getVideoID()]?.titles?.[0];
if (title && title.title && (title.locked || title.votes > 0)) {
Config.config.showDeArrowPromotion = false;
tooltip = new Tooltip({
text: chrome.i18n.getMessage("DeArrowTitleReplacementSuggestion") + "\n\n" + title.title,
linkOnClick: () => {
window.open("https://dearrow.ajay.app");
Config.config.shownDeArrowPromotion = true;
},
secondButtonText: chrome.i18n.getMessage("hideNewFeatureUpdates"),
referenceNode: element,
prependElement: element.firstElementChild as HTMLElement,
timeout: 15000,
positionRealtive: false,
containerAbsolute: true,
bottomOffset: "inherit",
topOffset: "55px",
leftOffset: "0",
rightOffset: "0",
topTriangle: true,
center: true,
opacity: 1
});
}
}
} catch { } // eslint-disable-line no-empty
} else {
Config.config.showDeArrowPromotion = false;
}
}
}
/**
* Two upper case words (at least 2 letters long)
*/
function badTitle(title: string): boolean {
return !!title.match(/\p{Lu}{2,} \p{Lu}{2,}[.!? ]/u);
}
export function hideDeArrowPromotion(): void {
if (tooltip) tooltip.close();
}

View File

@@ -3,6 +3,7 @@ import Config from "./config";
import { showDonationLink } from "./utils/configUtils";
import { waitFor } from "../maze-utils/src";
import { isDeArrowInstalled } from "./utils/crossExtension";
if (document.readyState === "complete") {
init();
@@ -10,6 +11,32 @@ if (document.readyState === "complete") {
document.addEventListener("DOMContentLoaded", init);
}
// DeArrow promotion
waitFor(() => Config.isReady()).then(() => {
if (Config.config.showNewFeaturePopups && Config.config.showUpsells) {
isDeArrowInstalled().then((installed) => {
if (!installed) {
const deArrowPromotion = document.getElementById("dearrow-link");
deArrowPromotion.classList.remove("hidden");
deArrowPromotion.addEventListener("click", () => Config.config.showDeArrowPromotion = false);
const text = deArrowPromotion.querySelector("#dearrow-link-text");
text.textContent = `${chrome.i18n.getMessage("DeArrowPromotionMessage2").split("?")[0]}? ${chrome.i18n.getMessage("DeArrowPromotionMessage3")}`;
const closeButton = deArrowPromotion.querySelector(".close-button");
closeButton.addEventListener("click", (e) => {
e.preventDefault();
deArrowPromotion.classList.add("hidden");
Config.config.showDeArrowPromotion = false;
Config.config.showDeArrowInSettings = false;
});
}
});
}
});
async function init() {
localizeHtmlPage();

View File

@@ -27,6 +27,7 @@ export interface PreviewBarSegment {
description: string;
source: SponsorSourceType;
requiredSegment?: boolean;
selectedSegment?: boolean;
}
interface ChapterGroup extends SegmentContainer {
@@ -332,6 +333,7 @@ class PreviewBar {
const bar = document.createElement('li');
bar.classList.add('previewbar');
if (barSegment.requiredSegment) bar.classList.add("requiredSegment");
if (barSegment.selectedSegment) bar.classList.add("selectedSegment");
bar.innerHTML = showLarger ? '&nbsp;&nbsp;' : '&nbsp;';
const fullCategoryName = (unsubmitted ? 'preview-' : '') + category;

View File

@@ -1,11 +1,12 @@
import Config from "../config";
import { SponsorTime } from "../types";
import { SegmentUUID, SponsorTime } from "../types";
import { getSkippingText } from "../utils/categoryUtils";
import { AnimationUtils } from "../utils/animationUtils";
import { keybindToString } from "../../maze-utils/src/config";
export interface SkipButtonControlBarProps {
skip: (segment: SponsorTime) => void;
selectSegment: (UUID: SegmentUUID) => void;
onMobileYouTube: boolean;
}
@@ -41,7 +42,7 @@ export class SkipButtonControlBar {
this.container = document.createElement("div");
this.container.classList.add("skipButtonControlBarContainer");
this.container.classList.add("hidden");
this.container.classList.add("sbhidden");
if (this.onMobileYouTube) this.container.classList.add("mobile");
this.skipIcon = document.createElement("img");
@@ -54,8 +55,18 @@ export class SkipButtonControlBar {
this.container.appendChild(this.skipIcon);
this.container.appendChild(this.textContainer);
this.container.addEventListener("click", () => this.toggleSkip());
this.container.addEventListener("mouseenter", () => this.stopTimer());
this.container.addEventListener("mouseleave", () => this.startTimer());
this.container.addEventListener("mouseenter", () => {
this.stopTimer();
if (this.segment) {
props.selectSegment(this.segment.UUID);
}
});
this.container.addEventListener("mouseleave", () => {
this.startTimer();
props.selectSegment(null);
});
if (this.onMobileYouTube) {
this.container.addEventListener("touchstart", (e) => this.handleTouchStart(e));
this.container.addEventListener("touchmove", (e) => this.handleTouchMove(e));
@@ -103,7 +114,7 @@ export class SkipButtonControlBar {
this.refreshText();
this.container?.classList?.remove("textDisabled");
this.textContainer?.classList?.remove("hidden");
this.textContainer?.classList?.remove("sbhidden");
AnimationUtils.disableAutoHideAnimation(this.skipIcon);
this.startTimer();
@@ -111,8 +122,8 @@ export class SkipButtonControlBar {
refreshText(): void {
if (this.segment) {
this.chapterText?.classList?.add("hidden");
this.container.classList.remove("hidden");
this.chapterText?.classList?.add("sbhidden");
this.container.classList.remove("sbhidden");
this.textContainer.innerText = this.getTitle();
this.skipIcon.setAttribute("title", this.getTitle());
}
@@ -134,10 +145,10 @@ export class SkipButtonControlBar {
}
disable(): void {
this.container.classList.add("hidden");
this.container.classList.add("sbhidden");
this.chapterText?.classList?.remove("hidden");
this.getChapterPrefix()?.classList?.remove("hidden");
this.chapterText?.classList?.remove("sbhidden");
this.getChapterPrefix()?.classList?.remove("sbhidden");
this.enabled = false;
}
@@ -147,8 +158,10 @@ export class SkipButtonControlBar {
}
toggleSkip(): void {
this.skip(this.segment);
this.disableText();
if (this.segment && this.enabled) {
this.skip(this.segment);
this.disableText();
}
}
disableText(): void {
@@ -158,10 +171,10 @@ export class SkipButtonControlBar {
}
this.container.classList.add("textDisabled");
this.textContainer?.classList?.add("hidden");
this.chapterText?.classList?.remove("hidden");
this.textContainer?.classList?.add("sbhidden");
this.chapterText?.classList?.remove("sbhidden");
this.getChapterPrefix()?.classList?.add("hidden");
this.getChapterPrefix()?.classList?.add("sbhidden");
AnimationUtils.enableAutoHideAnimation(this.skipIcon);
if (this.onMobileYouTube) {
@@ -182,7 +195,7 @@ export class SkipButtonControlBar {
}
private getTitle(): string {
return getSkippingText([this.segment], false) + (this.showKeybindHint ? " (" + keybindToString(Config.config.skipKeybind) + ")" : "");
return getSkippingText([this.segment], false) + (this.showKeybindHint ? " (" + keybindToString(Config.config.skipToHighlightKeybind) + ")" : "");
}
private getChapterPrefix(): HTMLElement {

View File

@@ -31,7 +31,7 @@ interface IsInfoFoundMessage {
}
interface SkipMessage {
message: "unskip" | "reskip";
message: "unskip" | "reskip" | "selectSegment";
UUID: SegmentUUID;
}

View File

@@ -18,6 +18,7 @@ import { StorageChangesObject } from "../maze-utils/src/config";
import { getHash } from "../maze-utils/src/hash";
import { isFirefoxOrSafari } from "../maze-utils/src";
import { isDeArrowInstalled } from "./utils/crossExtension";
import { asyncRequestToServer } from "./utils/requests";
const utils = new Utils();
let embed = false;
@@ -74,17 +75,29 @@ async function init() {
}
// DeArrow promotion
if (Config.config.showNewFeaturePopups && Config.config.showUpsells) {
if (Config.config.showNewFeaturePopups && Config.config.showUpsells && Config.config.showDeArrowInSettings) {
isDeArrowInstalled().then((installed) => {
if (!installed) {
const deArrowPromotion = document.getElementById("deArrowPromotion");
deArrowPromotion.classList.remove("hidden");
deArrowPromotion.addEventListener("click", () => Config.config.showDeArrowPromotion = false);
const closeButton = deArrowPromotion.querySelector(".close-button");
closeButton.addEventListener("click", (e) => {
e.preventDefault();
deArrowPromotion.classList.add("hidden");
Config.config.showDeArrowPromotion = false;
Config.config.showDeArrowInSettings = false;
});
}
});
}
const skipToHighlightKeybind = document.querySelector(`[data-sync="skipToHighlightKeybind"] .optionLabel`) as HTMLElement;
skipToHighlightKeybind.innerText = `${chrome.i18n.getMessage("skip_to_category").replace("{0}", chrome.i18n.getMessage("category_poi_highlight")).replace("?", "")}:`;
// Set all of the toggle options to the correct option
const optionsContainer = document.getElementById("options");
const optionsElements = optionsContainer.querySelectorAll("*");
@@ -555,7 +568,7 @@ function activatePrivateTextChange(element: HTMLElement) {
switch (option) {
case "userID":
if (Config.config[option]) {
utils.asyncRequestToServer("GET", "/api/userInfo", {
asyncRequestToServer("GET", "/api/userInfo", {
publicUserID: getHash(Config.config[option]),
values: ["warnings", "banned"]
}).then((result) => {

View File

@@ -27,6 +27,7 @@ import GenericNotice from "./render/GenericNotice";
import { getErrorMessage, getFormattedTime } from "../maze-utils/src/formating";
import { StorageChangesObject } from "../maze-utils/src/config";
import { getHash } from "../maze-utils/src/hash";
import { asyncRequestToServer, sendRequestToServer } from "./utils/requests";
const utils = new Utils();
@@ -71,6 +72,12 @@ window.addEventListener("message", async (e): Promise<void> => {
if (e.source !== window.parent) return;
if (e.origin.endsWith('.youtube.com')) {
allowPopup = true;
if (e.data && e.data?.type === "style") {
const style = document.createElement("style");
style.textContent = e.data.css;
document.head.appendChild(style);
}
}
});
@@ -108,6 +115,10 @@ async function runThePopup(messageListener?: MessageListener): Promise<void> {
const PageElements: PageElements = {};
[
"sbPopupLogo",
"sbYourWorkBox",
"videoInfo",
"sbFooter",
"sponsorBlockPopupBody",
"sponsorblockPopup",
"sponsorStart",
@@ -198,6 +209,16 @@ async function runThePopup(messageListener?: MessageListener): Promise<void> {
}
PageElements.sbDonate.addEventListener("click", () => Config.config.donateClicked = Config.config.donateClicked + 1);
if (Config.config.cleanPopup) {
PageElements.sbPopupLogo.classList.add("hidden");
PageElements.sbYourWorkBox.classList.add("hidden");
PageElements.sbFooter.classList.add("hidden");
PageElements.sponsorTimesDonateContainer.classList.add("hidden");
PageElements.mainControls.classList.add("hidden");
PageElements.videoInfo.style.marginTop = "10px";
}
if (Config.config.testingServer) {
PageElements.sbBetaServerWarning.classList.remove("hidden");
PageElements.sbBetaServerWarning.addEventListener("click", function () {
@@ -281,7 +302,7 @@ async function runThePopup(messageListener?: MessageListener): Promise<void> {
const values = ["userName", "viewCount", "minutesSaved", "vip", "permissions"];
utils.asyncRequestToServer("GET", "/api/userInfo", {
asyncRequestToServer("GET", "/api/userInfo", {
publicUserID: await getHash(Config.config.userID),
values
}).then((res) => {
@@ -687,6 +708,8 @@ async function runThePopup(messageListener?: MessageListener): Promise<void> {
: chrome.i18n.getMessage("skipSegment");
skipButton.addEventListener("click", () => skipSegment(actionType, UUID, skipButton));
votingButtons.addEventListener("dblclick", () => skipSegment(actionType, UUID));
votingButtons.addEventListener("dblclick", () => skipSegment(actionType, UUID));
votingButtons.addEventListener("mouseenter", () => selectSegment(UUID));
//add thumbs up, thumbs down and uuid copy buttons to the container
voteButtonsContainer.appendChild(upvoteButton);
@@ -718,6 +741,8 @@ async function runThePopup(messageListener?: MessageListener): Promise<void> {
container.appendChild(votingButtons);
}
container.addEventListener("mouseleave", () => selectSegment(null));
}
function submitTimes() {
@@ -800,7 +825,7 @@ async function runThePopup(messageListener?: MessageListener): Promise<void> {
PageElements.setUsernameStatus.style.display = "unset";
PageElements.setUsernameStatus.innerText = chrome.i18n.getMessage("Loading");
utils.sendRequestToServer("POST", "/api/setUsername?userID=" + Config.config.userID + "&username=" + PageElements.usernameInput.value, function (response) {
sendRequestToServer("POST", "/api/setUsername?userID=" + Config.config.userID + "&username=" + PageElements.usernameInput.value, function (response) {
if (response.status == 200) {
//submitted
PageElements.submitUsername.style.display = "none";
@@ -968,6 +993,13 @@ async function runThePopup(messageListener?: MessageListener): Promise<void> {
}
}
function selectSegment(UUID: SegmentUUID | null): void {
sendTabMessage({
message: "selectSegment",
UUID: UUID
});
}
/**
* Should skipping be disabled (visuals stay)
*/
@@ -1041,9 +1073,10 @@ async function runThePopup(messageListener?: MessageListener): Promise<void> {
*/
function getFormattedHours(minutes) {
minutes = Math.round(minutes * 10) / 10;
const days = Math.floor(minutes / 1440);
const years = Math.floor(minutes / 525600); // Assumes 365.0 days in a year
const days = Math.floor(minutes / 1440) % 365;
const hours = Math.floor(minutes / 60) % 24;
return (days > 0 ? days + chrome.i18n.getMessage("dayAbbreviation") + " " : "") + (hours > 0 ? hours + chrome.i18n.getMessage("hourAbbreviation") + " " : "") + (minutes % 60).toFixed(1);
return (years > 0 ? years + chrome.i18n.getMessage("yearAbbreviation") + " " : "") + (days > 0 ? days + chrome.i18n.getMessage("dayAbbreviation") + " " : "") + (hours > 0 ? hours + chrome.i18n.getMessage("hourAbbreviation") + " " : "") + (minutes % 60).toFixed(1);
}
function contentConfigUpdateListener(changes: StorageChangesObject) {

View File

@@ -2,10 +2,8 @@ import Config, { VideoDownvotes } from "./config";
import { CategorySelection, SponsorTime, BackgroundScriptContainer, Registration, VideoID, SponsorHideType, CategorySkipOption } from "./types";
import { getHash, HashedValue } from "../maze-utils/src/hash";
import * as CompileConfig from "../config.json";
import { isFirefoxOrSafari, waitFor } from "../maze-utils/src";
import { findValidElementFromSelector } from "../maze-utils/src/dom";
import { FetchResponse, sendRequestToCustomServer } from "../maze-utils/src/background-request-proxy"
import { isSafari } from "../maze-utils/src/config";
export default class Utils {
@@ -240,50 +238,6 @@ export default class Utils {
return permissionRegex;
}
/**
* Sends a request to a custom server
*
* @param type The request type. "GET", "POST", etc.
* @param address The address to add to the SponsorBlock server address
* @param callback
*/
asyncRequestToCustomServer(type: string, url: string, data = {}): Promise<FetchResponse> {
return sendRequestToCustomServer(type, url, data);
}
/**
* Sends a request to the SponsorBlock server with address added as a query
*
* @param type The request type. "GET", "POST", etc.
* @param address The address to add to the SponsorBlock server address
* @param callback
*/
async asyncRequestToServer(type: string, address: string, data = {}): Promise<FetchResponse> {
const serverAddress = Config.config.testingServer ? CompileConfig.testingServerAddress : Config.config.serverAddress;
return await (this.asyncRequestToCustomServer(type, serverAddress + address, data));
}
/**
* Sends a request to the SponsorBlock server with address added as a query
*
* @param type The request type. "GET", "POST", etc.
* @param address The address to add to the SponsorBlock server address
* @param callback
*/
sendRequestToServer(type: string, address: string, callback?: (response: FetchResponse) => void): void {
const serverAddress = Config.config.testingServer ? CompileConfig.testingServerAddress : Config.config.serverAddress;
// Ask the background script to do the work
chrome.runtime.sendMessage({
message: "sendRequest",
type,
url: serverAddress + address
}, (response) => {
callback(response);
});
}
findReferenceNode(): HTMLElement {
const selectors = [
"#player-container-id", // Mobile YouTube

View File

@@ -27,7 +27,7 @@ function applyLoadingAnimation(element: HTMLElement, time: number, callback?: ()
function setupCustomHideAnimation(element: Element, container: Element, enabled = true, rightSlide = true): { hide: () => void; show: () => void } {
if (enabled) element.classList.add("autoHiding");
element.classList.add("hidden");
element.classList.add("sbhidden");
element.classList.add("animationDone");
if (!rightSlide) element.classList.add("autoHideLeft");
@@ -37,7 +37,7 @@ function setupCustomHideAnimation(element: Element, container: Element, enabled
hide: () => {
mouseEntered = false;
if (element.classList.contains("autoHiding")) {
element.classList.add("hidden");
element.classList.add("sbhidden");
}
},
show: () => {
@@ -46,7 +46,7 @@ function setupCustomHideAnimation(element: Element, container: Element, enabled
// Wait for next event loop
setTimeout(() => {
if (mouseEntered) element.classList.remove("hidden")
if (mouseEntered) element.classList.remove("sbhidden")
}, 10);
}
};
@@ -61,12 +61,12 @@ function setupAutoHideAnimation(element: Element, container: Element, enabled =
function enableAutoHideAnimation(element: Element): void {
element.classList.add("autoHiding");
element.classList.add("hidden");
element.classList.add("sbhidden");
}
function disableAutoHideAnimation(element: Element): void {
element.classList.remove("autoHiding");
element.classList.remove("hidden");
element.classList.remove("sbhidden");
}
export const AnimationUtils = {

View File

@@ -106,5 +106,5 @@ export function exportTimesAsHashParam(segments: SponsorTime[]): string {
export function normalizeChapterName(description: string): string {
return description.toLowerCase().replace(/\.|:|-/g, "").replace(/\s+/g, " ");
return description.toLowerCase().replace(/[.:'`"-]/ug, "").replace(/\s+/g, " ");
}

View File

@@ -4,20 +4,17 @@ function getLuminance(color: string): number {
return Math.sqrt(0.299 * (r * r) + 0.587 * (g * g) + 0.114 * (b * b));
}
/* From https://stackoverflow.com/a/5624139 */
function hexToRgb(hex: string): {r: number; g: number; b: number} {
// Expand shorthand form (e.g. "03F") to full form (e.g. "0033FF")
const shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
hex = hex.replace(shorthandRegex, function(m, r, g, b) {
return r + r + g + g + b + b;
});
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
return result ? {
r: parseInt(result[1], 16),
g: parseInt(result[2], 16),
b: parseInt(result[3], 16)
} : null;
/* Converts hex color to rgb color */
const hexChars = "0123456789abcdef";
function hexToRgb(hex: string): { r: number; g: number; b: number } | null {
if (hex.length == 4)
hex = "#" + hex[1] + hex[1] + hex[2] + hex[2] + hex[3] + hex[3];
return /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex)
? {
r: hexChars.indexOf(hex[1]) * 16 + hexChars.indexOf(hex[2]),
g: hexChars.indexOf(hex[3]) * 16 + hexChars.indexOf(hex[4]),
b: hexChars.indexOf(hex[5]) * 16 + hexChars.indexOf(hex[6]),
}: null;
}
/**
@@ -31,4 +28,4 @@ function indexesOf<T>(array: T[], value: T): number[] {
export const GenericUtils = {
getLuminance,
indexesOf
}
}

47
src/utils/requests.ts Normal file
View File

@@ -0,0 +1,47 @@
import Config from "../config";
import * as CompileConfig from "../../config.json";
import { FetchResponse, sendRequestToCustomServer } from "../../maze-utils/src/background-request-proxy";
/**
* Sends a request to a custom server
*
* @param type The request type. "GET", "POST", etc.
* @param address The address to add to the SponsorBlock server address
* @param callback
*/
export function asyncRequestToCustomServer(type: string, url: string, data = {}): Promise<FetchResponse> {
return sendRequestToCustomServer(type, url, data);
}
/**
* Sends a request to the SponsorBlock server with address added as a query
*
* @param type The request type. "GET", "POST", etc.
* @param address The address to add to the SponsorBlock server address
* @param callback
*/
export async function asyncRequestToServer(type: string, address: string, data = {}): Promise<FetchResponse> {
const serverAddress = Config.config.testingServer ? CompileConfig.testingServerAddress : Config.config.serverAddress;
return await (asyncRequestToCustomServer(type, serverAddress + address, data));
}
/**
* Sends a request to the SponsorBlock server with address added as a query
*
* @param type The request type. "GET", "POST", etc.
* @param address The address to add to the SponsorBlock server address
* @param callback
*/
export function sendRequestToServer(type: string, address: string, callback?: (response: FetchResponse) => void): void {
const serverAddress = Config.config.testingServer ? CompileConfig.testingServerAddress : Config.config.serverAddress;
// Ask the background script to do the work
chrome.runtime.sendMessage({
message: "sendRequest",
type,
url: serverAddress + address
}, (response) => {
callback(response);
});
}

View File

@@ -2,6 +2,7 @@ import { Category, CategorySkipOption, VideoID } from "../types";
import { getHash } from "../../maze-utils/src/hash";
import Utils from "../utils";
import { logWarn } from "./logger";
import { asyncRequestToServer } from "./requests";
const utils = new Utils();
@@ -20,7 +21,7 @@ async function getLabelHashBlock(hashPrefix: string): Promise<LabelCacheEntry |
return cachedEntry;
}
const response = await utils.asyncRequestToServer("GET", `/api/videoLabels/${hashPrefix}`);
const response = await asyncRequestToServer("GET", `/api/videoLabels/${hashPrefix}`);
if (response.status !== 200) {
// No video labels or server down
labelCache[hashPrefix] = {

View File

@@ -3,8 +3,7 @@ import { getHash } from "../../maze-utils/src/hash";
import Config from "../config";
import GenericNotice, { NoticeOptions } from "../render/GenericNotice";
import { ContentContainer } from "../types";
import Utils from "../utils";
const utils = new Utils();
import { asyncRequestToServer } from "./requests";
export interface ChatConfig {
displayName: string;
@@ -13,20 +12,20 @@ export interface ChatConfig {
}
export async function openWarningDialog(contentContainer: ContentContainer): Promise<void> {
const userInfo = await utils.asyncRequestToServer("GET", "/api/userInfo", {
const userInfo = await asyncRequestToServer("GET", "/api/userInfo", {
publicUserID: await getHash(Config.config.userID),
values: ["warningReason"]
});
if (userInfo.ok) {
const warningReason = JSON.parse(userInfo.responseText)?.warningReason;
const userNameData = await utils.asyncRequestToServer("GET", "/api/getUsername?userID=" + Config.config.userID);
const userNameData = await asyncRequestToServer("GET", "/api/getUsername?userID=" + Config.config.userID);
const userName = userNameData.ok ? JSON.parse(userNameData.responseText).userName : "";
const publicUserID = await getHash(Config.config.userID);
let notice: GenericNotice = null;
const options: NoticeOptions = {
title: chrome.i18n.getMessage("warningTitle"),
title: chrome.i18n.getMessage("deArrowMessageRecieved"),
textBoxes: [{
text: chrome.i18n.getMessage("warningChatInfo"),
icon: null
@@ -43,7 +42,7 @@ export async function openWarningDialog(contentContainer: ContentContainer): Pro
{
name: chrome.i18n.getMessage("warningConfirmButton"),
listener: async () => {
const result = await utils.asyncRequestToServer("POST", "/api/warnUser", {
const result = await asyncRequestToServer("POST", "/api/warnUser", {
userID: Config.config.userID,
enabled: false
});