mirror of
https://github.com/nkcmr/HyperTab.git
synced 2026-04-30 12:44:32 +02:00
Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
42865ff2bb | ||
|
|
ced8d54eb0 | ||
|
|
170ebf971d | ||
|
|
6dc2074870 | ||
|
|
0ce204a948 | ||
|
|
4f2db92534 |
19
LICENSE
Normal file
19
LICENSE
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
Copyright (c) 2024 Nicholas Comer
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
this software and associated documentation files (the "Software"), to deal in
|
||||||
|
the Software without restriction, including without limitation the rights to
|
||||||
|
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
of the Software, and to permit persons to whom the Software is furnished to do
|
||||||
|
so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
17
README.md
Normal file
17
README.md
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
# HyperTab
|
||||||
|
|
||||||
|
A brutally simple browser extension that targets Firefox meant to be a replica of Chrome's tab switcher. Quickly open, search, then switch to any open tab.
|
||||||
|
|
||||||
|
https://github.com/nkcmr/HyperTab/assets/1791521/c60acea5-23c3-4c80-9288-518d06dcc83a
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
Open tab search with <kbd>⌘</kbd> + <kbd>Shift</kbd> + <kbd>E</kbd> (it would be <kbd>A</kbd>, but Firefox uses this for add-on management). Search is automatically focused so you should be able to type some fuzzy search and immediately narrow down what you're looking for.
|
||||||
|
|
||||||
|
## Why?
|
||||||
|
|
||||||
|
Switching from Chrome to Firefox is mostly fine. But Firefox's current "story" for navigating between tabs is really sub-par (IMO). This extension, for me, implements a _must have_ feature for any browser I am using: Quick tab search and switch.
|
||||||
|
|
||||||
|
## Privacy/Security
|
||||||
|
|
||||||
|
You're probably here to make sure this extension isn't doing anything sneak, right? Good for you, everyone who is able to understand code should do this. Have a look around and see for yourself. **But,** I will save you a bunch of time: this browser extension does not persist anything and does not talk to any servers; it doesn't need to!
|
||||||
@@ -36,5 +36,5 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
"permissions": ["tabs", "*://*/*"]
|
"permissions": ["tabs", "tabGroups", "*://*/*"]
|
||||||
}
|
}
|
||||||
|
|||||||
401
package-lock.json
generated
401
package-lock.json
generated
@@ -7,23 +7,24 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/chrome": "^0.0.251",
|
"@types/chrome": "^0.0.251",
|
||||||
"@types/lodash.uniq": "^4.5.9",
|
"@types/lodash.uniq": "^4.5.9",
|
||||||
"@types/react": "^18.2.37",
|
"@types/react": "^18.3.23",
|
||||||
"@types/react-dom": "^18.2.15",
|
"@types/react-dom": "^18.3.7",
|
||||||
"esbuild": "^0.19.5",
|
"esbuild": "^0.19.12",
|
||||||
"fuse.js": "^7.0.0",
|
"fuse.js": "^7.1.0",
|
||||||
"lodash.uniq": "^4.5.0",
|
"lodash.uniq": "^4.5.0",
|
||||||
"npm-run-all": "^4.1.5",
|
"npm-run-all": "^4.1.5",
|
||||||
"react": "^18.2.0",
|
"react": "^18.3.1",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.3.1",
|
||||||
"react-hotkeys-hook": "^4.4.1",
|
"react-hotkeys-hook": "^4.6.2",
|
||||||
"styled-components": "^6.1.9",
|
"styled-components": "^6.1.18",
|
||||||
"typescript": "^5.2.2"
|
"typescript": "^5.8.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@emotion/is-prop-valid": {
|
"node_modules/@emotion/is-prop-valid": {
|
||||||
"version": "1.2.1",
|
"version": "1.2.2",
|
||||||
"resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.2.tgz",
|
||||||
"integrity": "sha512-61Mf7Ufx4aDxx1xlDeOm8aFFigGHE4z+0sKCa+IHCeZKiyP9RLD0Mmx7m8b9/Cf37f7NAvQOOJAbQQGVr5uERw==",
|
"integrity": "sha512-uNsoYd37AFmaCdXlg6EYD1KaPOaRWRByMCYzbKUX4+hhMfrxdVSelShywL4JVaAeM/eHUOSprYBQls+/neX3pw==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@emotion/memoize": "^0.8.1"
|
"@emotion/memoize": "^0.8.1"
|
||||||
}
|
}
|
||||||
@@ -31,20 +32,38 @@
|
|||||||
"node_modules/@emotion/memoize": {
|
"node_modules/@emotion/memoize": {
|
||||||
"version": "0.8.1",
|
"version": "0.8.1",
|
||||||
"resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz",
|
"resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz",
|
||||||
"integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA=="
|
"integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==",
|
||||||
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@emotion/unitless": {
|
"node_modules/@emotion/unitless": {
|
||||||
"version": "0.8.1",
|
"version": "0.8.1",
|
||||||
"resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz",
|
"resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz",
|
||||||
"integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ=="
|
"integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ=="
|
||||||
},
|
},
|
||||||
|
"node_modules/@esbuild/aix-ppc64": {
|
||||||
|
"version": "0.19.12",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz",
|
||||||
|
"integrity": "sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==",
|
||||||
|
"cpu": [
|
||||||
|
"ppc64"
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"aix"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@esbuild/android-arm": {
|
"node_modules/@esbuild/android-arm": {
|
||||||
"version": "0.19.5",
|
"version": "0.19.12",
|
||||||
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.5.tgz",
|
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.12.tgz",
|
||||||
"integrity": "sha512-bhvbzWFF3CwMs5tbjf3ObfGqbl/17ict2/uwOSfr3wmxDE6VdS2GqY/FuzIPe0q0bdhj65zQsvqfArI9MY6+AA==",
|
"integrity": "sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm"
|
"arm"
|
||||||
],
|
],
|
||||||
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"android"
|
"android"
|
||||||
@@ -54,12 +73,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@esbuild/android-arm64": {
|
"node_modules/@esbuild/android-arm64": {
|
||||||
"version": "0.19.5",
|
"version": "0.19.12",
|
||||||
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.5.tgz",
|
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.12.tgz",
|
||||||
"integrity": "sha512-5d1OkoJxnYQfmC+Zd8NBFjkhyCNYwM4n9ODrycTFY6Jk1IGiZ+tjVJDDSwDt77nK+tfpGP4T50iMtVi4dEGzhQ==",
|
"integrity": "sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"android"
|
"android"
|
||||||
@@ -69,12 +89,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@esbuild/android-x64": {
|
"node_modules/@esbuild/android-x64": {
|
||||||
"version": "0.19.5",
|
"version": "0.19.12",
|
||||||
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.5.tgz",
|
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.12.tgz",
|
||||||
"integrity": "sha512-9t+28jHGL7uBdkBjL90QFxe7DVA+KGqWlHCF8ChTKyaKO//VLuoBricQCgwhOjA1/qOczsw843Fy4cbs4H3DVA==",
|
"integrity": "sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"android"
|
"android"
|
||||||
@@ -84,12 +105,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@esbuild/darwin-arm64": {
|
"node_modules/@esbuild/darwin-arm64": {
|
||||||
"version": "0.19.5",
|
"version": "0.19.12",
|
||||||
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.5.tgz",
|
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.12.tgz",
|
||||||
"integrity": "sha512-mvXGcKqqIqyKoxq26qEDPHJuBYUA5KizJncKOAf9eJQez+L9O+KfvNFu6nl7SCZ/gFb2QPaRqqmG0doSWlgkqw==",
|
"integrity": "sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"darwin"
|
"darwin"
|
||||||
@@ -99,12 +121,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@esbuild/darwin-x64": {
|
"node_modules/@esbuild/darwin-x64": {
|
||||||
"version": "0.19.5",
|
"version": "0.19.12",
|
||||||
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.5.tgz",
|
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.12.tgz",
|
||||||
"integrity": "sha512-Ly8cn6fGLNet19s0X4unjcniX24I0RqjPv+kurpXabZYSXGM4Pwpmf85WHJN3lAgB8GSth7s5A0r856S+4DyiA==",
|
"integrity": "sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"darwin"
|
"darwin"
|
||||||
@@ -114,12 +137,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@esbuild/freebsd-arm64": {
|
"node_modules/@esbuild/freebsd-arm64": {
|
||||||
"version": "0.19.5",
|
"version": "0.19.12",
|
||||||
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.5.tgz",
|
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.12.tgz",
|
||||||
"integrity": "sha512-GGDNnPWTmWE+DMchq1W8Sd0mUkL+APvJg3b11klSGUDvRXh70JqLAO56tubmq1s2cgpVCSKYywEiKBfju8JztQ==",
|
"integrity": "sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"freebsd"
|
"freebsd"
|
||||||
@@ -129,12 +153,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@esbuild/freebsd-x64": {
|
"node_modules/@esbuild/freebsd-x64": {
|
||||||
"version": "0.19.5",
|
"version": "0.19.12",
|
||||||
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.5.tgz",
|
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.12.tgz",
|
||||||
"integrity": "sha512-1CCwDHnSSoA0HNwdfoNY0jLfJpd7ygaLAp5EHFos3VWJCRX9DMwWODf96s9TSse39Br7oOTLryRVmBoFwXbuuQ==",
|
"integrity": "sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"freebsd"
|
"freebsd"
|
||||||
@@ -144,12 +169,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@esbuild/linux-arm": {
|
"node_modules/@esbuild/linux-arm": {
|
||||||
"version": "0.19.5",
|
"version": "0.19.12",
|
||||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.5.tgz",
|
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.12.tgz",
|
||||||
"integrity": "sha512-lrWXLY/vJBzCPC51QN0HM71uWgIEpGSjSZZADQhq7DKhPcI6NH1IdzjfHkDQws2oNpJKpR13kv7/pFHBbDQDwQ==",
|
"integrity": "sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm"
|
"arm"
|
||||||
],
|
],
|
||||||
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"linux"
|
"linux"
|
||||||
@@ -159,12 +185,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@esbuild/linux-arm64": {
|
"node_modules/@esbuild/linux-arm64": {
|
||||||
"version": "0.19.5",
|
"version": "0.19.12",
|
||||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.5.tgz",
|
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.12.tgz",
|
||||||
"integrity": "sha512-o3vYippBmSrjjQUCEEiTZ2l+4yC0pVJD/Dl57WfPwwlvFkrxoSO7rmBZFii6kQB3Wrn/6GwJUPLU5t52eq2meA==",
|
"integrity": "sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"linux"
|
"linux"
|
||||||
@@ -174,12 +201,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@esbuild/linux-ia32": {
|
"node_modules/@esbuild/linux-ia32": {
|
||||||
"version": "0.19.5",
|
"version": "0.19.12",
|
||||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.5.tgz",
|
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.12.tgz",
|
||||||
"integrity": "sha512-MkjHXS03AXAkNp1KKkhSKPOCYztRtK+KXDNkBa6P78F8Bw0ynknCSClO/ztGszILZtyO/lVKpa7MolbBZ6oJtQ==",
|
"integrity": "sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"ia32"
|
"ia32"
|
||||||
],
|
],
|
||||||
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"linux"
|
"linux"
|
||||||
@@ -189,12 +217,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@esbuild/linux-loong64": {
|
"node_modules/@esbuild/linux-loong64": {
|
||||||
"version": "0.19.5",
|
"version": "0.19.12",
|
||||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.5.tgz",
|
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.12.tgz",
|
||||||
"integrity": "sha512-42GwZMm5oYOD/JHqHska3Jg0r+XFb/fdZRX+WjADm3nLWLcIsN27YKtqxzQmGNJgu0AyXg4HtcSK9HuOk3v1Dw==",
|
"integrity": "sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"loong64"
|
"loong64"
|
||||||
],
|
],
|
||||||
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"linux"
|
"linux"
|
||||||
@@ -204,12 +233,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@esbuild/linux-mips64el": {
|
"node_modules/@esbuild/linux-mips64el": {
|
||||||
"version": "0.19.5",
|
"version": "0.19.12",
|
||||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.5.tgz",
|
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.12.tgz",
|
||||||
"integrity": "sha512-kcjndCSMitUuPJobWCnwQ9lLjiLZUR3QLQmlgaBfMX23UEa7ZOrtufnRds+6WZtIS9HdTXqND4yH8NLoVVIkcg==",
|
"integrity": "sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"mips64el"
|
"mips64el"
|
||||||
],
|
],
|
||||||
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"linux"
|
"linux"
|
||||||
@@ -219,12 +249,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@esbuild/linux-ppc64": {
|
"node_modules/@esbuild/linux-ppc64": {
|
||||||
"version": "0.19.5",
|
"version": "0.19.12",
|
||||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.5.tgz",
|
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.12.tgz",
|
||||||
"integrity": "sha512-yJAxJfHVm0ZbsiljbtFFP1BQKLc8kUF6+17tjQ78QjqjAQDnhULWiTA6u0FCDmYT1oOKS9PzZ2z0aBI+Mcyj7Q==",
|
"integrity": "sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"ppc64"
|
"ppc64"
|
||||||
],
|
],
|
||||||
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"linux"
|
"linux"
|
||||||
@@ -234,12 +265,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@esbuild/linux-riscv64": {
|
"node_modules/@esbuild/linux-riscv64": {
|
||||||
"version": "0.19.5",
|
"version": "0.19.12",
|
||||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.5.tgz",
|
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.12.tgz",
|
||||||
"integrity": "sha512-5u8cIR/t3gaD6ad3wNt1MNRstAZO+aNyBxu2We8X31bA8XUNyamTVQwLDA1SLoPCUehNCymhBhK3Qim1433Zag==",
|
"integrity": "sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"riscv64"
|
"riscv64"
|
||||||
],
|
],
|
||||||
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"linux"
|
"linux"
|
||||||
@@ -249,12 +281,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@esbuild/linux-s390x": {
|
"node_modules/@esbuild/linux-s390x": {
|
||||||
"version": "0.19.5",
|
"version": "0.19.12",
|
||||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.5.tgz",
|
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.12.tgz",
|
||||||
"integrity": "sha512-Z6JrMyEw/EmZBD/OFEFpb+gao9xJ59ATsoTNlj39jVBbXqoZm4Xntu6wVmGPB/OATi1uk/DB+yeDPv2E8PqZGw==",
|
"integrity": "sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"s390x"
|
"s390x"
|
||||||
],
|
],
|
||||||
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"linux"
|
"linux"
|
||||||
@@ -264,12 +297,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@esbuild/linux-x64": {
|
"node_modules/@esbuild/linux-x64": {
|
||||||
"version": "0.19.5",
|
"version": "0.19.12",
|
||||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.5.tgz",
|
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.12.tgz",
|
||||||
"integrity": "sha512-psagl+2RlK1z8zWZOmVdImisMtrUxvwereIdyJTmtmHahJTKb64pAcqoPlx6CewPdvGvUKe2Jw+0Z/0qhSbG1A==",
|
"integrity": "sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"linux"
|
"linux"
|
||||||
@@ -279,12 +313,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@esbuild/netbsd-x64": {
|
"node_modules/@esbuild/netbsd-x64": {
|
||||||
"version": "0.19.5",
|
"version": "0.19.12",
|
||||||
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.5.tgz",
|
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.12.tgz",
|
||||||
"integrity": "sha512-kL2l+xScnAy/E/3119OggX8SrWyBEcqAh8aOY1gr4gPvw76la2GlD4Ymf832UCVbmuWeTf2adkZDK+h0Z/fB4g==",
|
"integrity": "sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"netbsd"
|
"netbsd"
|
||||||
@@ -294,12 +329,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@esbuild/openbsd-x64": {
|
"node_modules/@esbuild/openbsd-x64": {
|
||||||
"version": "0.19.5",
|
"version": "0.19.12",
|
||||||
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.5.tgz",
|
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.12.tgz",
|
||||||
"integrity": "sha512-sPOfhtzFufQfTBgRnE1DIJjzsXukKSvZxloZbkJDG383q0awVAq600pc1nfqBcl0ice/WN9p4qLc39WhBShRTA==",
|
"integrity": "sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"openbsd"
|
"openbsd"
|
||||||
@@ -309,12 +345,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@esbuild/sunos-x64": {
|
"node_modules/@esbuild/sunos-x64": {
|
||||||
"version": "0.19.5",
|
"version": "0.19.12",
|
||||||
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.5.tgz",
|
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.12.tgz",
|
||||||
"integrity": "sha512-dGZkBXaafuKLpDSjKcB0ax0FL36YXCvJNnztjKV+6CO82tTYVDSH2lifitJ29jxRMoUhgkg9a+VA/B03WK5lcg==",
|
"integrity": "sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"sunos"
|
"sunos"
|
||||||
@@ -324,12 +361,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@esbuild/win32-arm64": {
|
"node_modules/@esbuild/win32-arm64": {
|
||||||
"version": "0.19.5",
|
"version": "0.19.12",
|
||||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.5.tgz",
|
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.12.tgz",
|
||||||
"integrity": "sha512-dWVjD9y03ilhdRQ6Xig1NWNgfLtf2o/STKTS+eZuF90fI2BhbwD6WlaiCGKptlqXlURVB5AUOxUj09LuwKGDTg==",
|
"integrity": "sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"win32"
|
"win32"
|
||||||
@@ -339,12 +377,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@esbuild/win32-ia32": {
|
"node_modules/@esbuild/win32-ia32": {
|
||||||
"version": "0.19.5",
|
"version": "0.19.12",
|
||||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.5.tgz",
|
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.12.tgz",
|
||||||
"integrity": "sha512-4liggWIA4oDgUxqpZwrDhmEfAH4d0iljanDOK7AnVU89T6CzHon/ony8C5LeOdfgx60x5cnQJFZwEydVlYx4iw==",
|
"integrity": "sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"ia32"
|
"ia32"
|
||||||
],
|
],
|
||||||
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"win32"
|
"win32"
|
||||||
@@ -354,12 +393,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@esbuild/win32-x64": {
|
"node_modules/@esbuild/win32-x64": {
|
||||||
"version": "0.19.5",
|
"version": "0.19.12",
|
||||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.5.tgz",
|
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.12.tgz",
|
||||||
"integrity": "sha512-czTrygUsB/jlM8qEW5MD8bgYU2Xg14lo6kBDXW6HdxKjh8M5PzETGiSHaz9MtbXBYDloHNUAUW2tMiKW4KM9Mw==",
|
"integrity": "sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"win32"
|
"win32"
|
||||||
@@ -414,32 +454,29 @@
|
|||||||
"integrity": "sha512-mxSnDQxPqsZxmeShFH+uwQ4kO4gcJcGahjjMFeLbKE95IAZiiZyiEepGZjtXJ7hN/yfu0bu9xN2ajcU0JcxX6A=="
|
"integrity": "sha512-mxSnDQxPqsZxmeShFH+uwQ4kO4gcJcGahjjMFeLbKE95IAZiiZyiEepGZjtXJ7hN/yfu0bu9xN2ajcU0JcxX6A=="
|
||||||
},
|
},
|
||||||
"node_modules/@types/react": {
|
"node_modules/@types/react": {
|
||||||
"version": "18.2.37",
|
"version": "18.3.23",
|
||||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.37.tgz",
|
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.23.tgz",
|
||||||
"integrity": "sha512-RGAYMi2bhRgEXT3f4B92WTohopH6bIXw05FuGlmJEnv/omEn190+QYEIYxIAuIBdKgboYYdVved2p1AxZVQnaw==",
|
"integrity": "sha512-/LDXMQh55EzZQ0uVAZmKKhfENivEvWz6E+EYzh+/MCjMhNsotd+ZHhBGIjFDTi6+fz0OhQQQLbTgdQIxxCsC0w==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/prop-types": "*",
|
"@types/prop-types": "*",
|
||||||
"@types/scheduler": "*",
|
|
||||||
"csstype": "^3.0.2"
|
"csstype": "^3.0.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@types/react-dom": {
|
"node_modules/@types/react-dom": {
|
||||||
"version": "18.2.15",
|
"version": "18.3.7",
|
||||||
"resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.15.tgz",
|
"resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.7.tgz",
|
||||||
"integrity": "sha512-HWMdW+7r7MR5+PZqJF6YFNSCtjz1T0dsvo/f1BV6HkV+6erD/nA7wd9NM00KVG83zf2nJ7uATPO9ttdIPvi3gg==",
|
"integrity": "sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==",
|
||||||
"dependencies": {
|
"license": "MIT",
|
||||||
"@types/react": "*"
|
"peerDependencies": {
|
||||||
|
"@types/react": "^18.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@types/scheduler": {
|
|
||||||
"version": "0.16.6",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.6.tgz",
|
|
||||||
"integrity": "sha512-Vlktnchmkylvc9SnwwwozTv04L/e1NykF5vgoQ0XTmI8DD+wxfjQuHuvHS3p0r2jz2x2ghPs2h1FVeDirIteWA=="
|
|
||||||
},
|
|
||||||
"node_modules/@types/stylis": {
|
"node_modules/@types/stylis": {
|
||||||
"version": "4.2.0",
|
"version": "4.2.5",
|
||||||
"resolved": "https://registry.npmjs.org/@types/stylis/-/stylis-4.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/@types/stylis/-/stylis-4.2.5.tgz",
|
||||||
"integrity": "sha512-n4sx2bqL0mW1tvDf/loQ+aMX7GQD3lc3fkCMC55VFNDu/vBOabO+LTIeXKM14xK0ppk5TUGcWRjiSpIlUpghKw=="
|
"integrity": "sha512-1Xve+NMN7FWjY14vLoY5tL3BVEQ/n42YLwaqJIPYhotZ9uBHt87VceMwWQpzmdEt2TNXIorIFG+YeCUUW7RInw==",
|
||||||
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/ansi-styles": {
|
"node_modules/ansi-styles": {
|
||||||
"version": "3.2.1",
|
"version": "3.2.1",
|
||||||
@@ -595,9 +632,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/csstype": {
|
"node_modules/csstype": {
|
||||||
"version": "3.1.2",
|
"version": "3.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
|
||||||
"integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ=="
|
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
|
||||||
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/define-data-property": {
|
"node_modules/define-data-property": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
@@ -718,10 +756,11 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/esbuild": {
|
"node_modules/esbuild": {
|
||||||
"version": "0.19.5",
|
"version": "0.19.12",
|
||||||
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.5.tgz",
|
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.12.tgz",
|
||||||
"integrity": "sha512-bUxalY7b1g8vNhQKdB24QDmHeY4V4tw/s6Ak5z+jJX9laP5MoQseTOMemAr0gxssjNcH0MCViG8ONI2kksvfFQ==",
|
"integrity": "sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==",
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
|
"license": "MIT",
|
||||||
"bin": {
|
"bin": {
|
||||||
"esbuild": "bin/esbuild"
|
"esbuild": "bin/esbuild"
|
||||||
},
|
},
|
||||||
@@ -729,28 +768,29 @@
|
|||||||
"node": ">=12"
|
"node": ">=12"
|
||||||
},
|
},
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
"@esbuild/android-arm": "0.19.5",
|
"@esbuild/aix-ppc64": "0.19.12",
|
||||||
"@esbuild/android-arm64": "0.19.5",
|
"@esbuild/android-arm": "0.19.12",
|
||||||
"@esbuild/android-x64": "0.19.5",
|
"@esbuild/android-arm64": "0.19.12",
|
||||||
"@esbuild/darwin-arm64": "0.19.5",
|
"@esbuild/android-x64": "0.19.12",
|
||||||
"@esbuild/darwin-x64": "0.19.5",
|
"@esbuild/darwin-arm64": "0.19.12",
|
||||||
"@esbuild/freebsd-arm64": "0.19.5",
|
"@esbuild/darwin-x64": "0.19.12",
|
||||||
"@esbuild/freebsd-x64": "0.19.5",
|
"@esbuild/freebsd-arm64": "0.19.12",
|
||||||
"@esbuild/linux-arm": "0.19.5",
|
"@esbuild/freebsd-x64": "0.19.12",
|
||||||
"@esbuild/linux-arm64": "0.19.5",
|
"@esbuild/linux-arm": "0.19.12",
|
||||||
"@esbuild/linux-ia32": "0.19.5",
|
"@esbuild/linux-arm64": "0.19.12",
|
||||||
"@esbuild/linux-loong64": "0.19.5",
|
"@esbuild/linux-ia32": "0.19.12",
|
||||||
"@esbuild/linux-mips64el": "0.19.5",
|
"@esbuild/linux-loong64": "0.19.12",
|
||||||
"@esbuild/linux-ppc64": "0.19.5",
|
"@esbuild/linux-mips64el": "0.19.12",
|
||||||
"@esbuild/linux-riscv64": "0.19.5",
|
"@esbuild/linux-ppc64": "0.19.12",
|
||||||
"@esbuild/linux-s390x": "0.19.5",
|
"@esbuild/linux-riscv64": "0.19.12",
|
||||||
"@esbuild/linux-x64": "0.19.5",
|
"@esbuild/linux-s390x": "0.19.12",
|
||||||
"@esbuild/netbsd-x64": "0.19.5",
|
"@esbuild/linux-x64": "0.19.12",
|
||||||
"@esbuild/openbsd-x64": "0.19.5",
|
"@esbuild/netbsd-x64": "0.19.12",
|
||||||
"@esbuild/sunos-x64": "0.19.5",
|
"@esbuild/openbsd-x64": "0.19.12",
|
||||||
"@esbuild/win32-arm64": "0.19.5",
|
"@esbuild/sunos-x64": "0.19.12",
|
||||||
"@esbuild/win32-ia32": "0.19.5",
|
"@esbuild/win32-arm64": "0.19.12",
|
||||||
"@esbuild/win32-x64": "0.19.5"
|
"@esbuild/win32-ia32": "0.19.12",
|
||||||
|
"@esbuild/win32-x64": "0.19.12"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/escape-string-regexp": {
|
"node_modules/escape-string-regexp": {
|
||||||
@@ -803,9 +843,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/fuse.js": {
|
"node_modules/fuse.js": {
|
||||||
"version": "7.0.0",
|
"version": "7.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/fuse.js/-/fuse.js-7.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/fuse.js/-/fuse.js-7.1.0.tgz",
|
||||||
"integrity": "sha512-14F4hBIxqKvD4Zz/XjDc3y94mNZN6pRv3U13Udo0lNLCWRBUsrMv2xwcF/y/Z5sV6+FQW+/ow68cHpm4sunt8Q==",
|
"integrity": "sha512-trLf4SzuuUxfusZADLINj+dE8clK1frKdmqiJNb1Es75fmI5oY6X2mxLVUciLLjxqw/xr72Dhy+lER6dGd02FQ==",
|
||||||
|
"license": "Apache-2.0",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=10"
|
"node": ">=10"
|
||||||
}
|
}
|
||||||
@@ -1215,15 +1256,16 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/nanoid": {
|
"node_modules/nanoid": {
|
||||||
"version": "3.3.7",
|
"version": "3.3.11",
|
||||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz",
|
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
|
||||||
"integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==",
|
"integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "github",
|
"type": "github",
|
||||||
"url": "https://github.com/sponsors/ai"
|
"url": "https://github.com/sponsors/ai"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"license": "MIT",
|
||||||
"bin": {
|
"bin": {
|
||||||
"nanoid": "bin/nanoid.cjs"
|
"nanoid": "bin/nanoid.cjs"
|
||||||
},
|
},
|
||||||
@@ -1341,9 +1383,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/picocolors": {
|
"node_modules/picocolors": {
|
||||||
"version": "1.0.0",
|
"version": "1.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
|
||||||
"integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ=="
|
"integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
|
||||||
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
"node_modules/pidtree": {
|
"node_modules/pidtree": {
|
||||||
"version": "0.3.1",
|
"version": "0.3.1",
|
||||||
@@ -1365,9 +1408,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/postcss": {
|
"node_modules/postcss": {
|
||||||
"version": "8.4.31",
|
"version": "8.4.49",
|
||||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz",
|
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz",
|
||||||
"integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==",
|
"integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==",
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "opencollective",
|
"type": "opencollective",
|
||||||
@@ -1382,10 +1425,11 @@
|
|||||||
"url": "https://github.com/sponsors/ai"
|
"url": "https://github.com/sponsors/ai"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"nanoid": "^3.3.6",
|
"nanoid": "^3.3.7",
|
||||||
"picocolors": "^1.0.0",
|
"picocolors": "^1.1.1",
|
||||||
"source-map-js": "^1.0.2"
|
"source-map-js": "^1.2.1"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^10 || ^12 || >=14"
|
"node": "^10 || ^12 || >=14"
|
||||||
@@ -1397,9 +1441,10 @@
|
|||||||
"integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ=="
|
"integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ=="
|
||||||
},
|
},
|
||||||
"node_modules/react": {
|
"node_modules/react": {
|
||||||
"version": "18.2.0",
|
"version": "18.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz",
|
||||||
"integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==",
|
"integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"loose-envify": "^1.1.0"
|
"loose-envify": "^1.1.0"
|
||||||
},
|
},
|
||||||
@@ -1408,21 +1453,23 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/react-dom": {
|
"node_modules/react-dom": {
|
||||||
"version": "18.2.0",
|
"version": "18.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz",
|
||||||
"integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==",
|
"integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"loose-envify": "^1.1.0",
|
"loose-envify": "^1.1.0",
|
||||||
"scheduler": "^0.23.0"
|
"scheduler": "^0.23.2"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"react": "^18.2.0"
|
"react": "^18.3.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/react-hotkeys-hook": {
|
"node_modules/react-hotkeys-hook": {
|
||||||
"version": "4.4.1",
|
"version": "4.6.2",
|
||||||
"resolved": "https://registry.npmjs.org/react-hotkeys-hook/-/react-hotkeys-hook-4.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/react-hotkeys-hook/-/react-hotkeys-hook-4.6.2.tgz",
|
||||||
"integrity": "sha512-sClBMBioFEgFGYLTWWRKvhxcCx1DRznd+wkFHwQZspnRBkHTgruKIHptlK/U/2DPX8BhHoRGzpMVWUXMmdZlmw==",
|
"integrity": "sha512-FmP+ZriY3EG59Ug/lxNfrObCnW9xQShgk7Nb83+CkpfkcCpfS95ydv+E9JuXA5cp8KtskU7LGlIARpkc92X22Q==",
|
||||||
|
"license": "MIT",
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"react": ">=16.8.1",
|
"react": ">=16.8.1",
|
||||||
"react-dom": ">=16.8.1"
|
"react-dom": ">=16.8.1"
|
||||||
@@ -1504,9 +1551,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/scheduler": {
|
"node_modules/scheduler": {
|
||||||
"version": "0.23.0",
|
"version": "0.23.2",
|
||||||
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz",
|
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz",
|
||||||
"integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==",
|
"integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"loose-envify": "^1.1.0"
|
"loose-envify": "^1.1.0"
|
||||||
}
|
}
|
||||||
@@ -1592,9 +1640,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/source-map-js": {
|
"node_modules/source-map-js": {
|
||||||
"version": "1.2.0",
|
"version": "1.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
|
||||||
"integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==",
|
"integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
|
||||||
|
"license": "BSD-3-Clause",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
@@ -1694,19 +1743,20 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/styled-components": {
|
"node_modules/styled-components": {
|
||||||
"version": "6.1.9",
|
"version": "6.1.18",
|
||||||
"resolved": "https://registry.npmjs.org/styled-components/-/styled-components-6.1.9.tgz",
|
"resolved": "https://registry.npmjs.org/styled-components/-/styled-components-6.1.18.tgz",
|
||||||
"integrity": "sha512-aBOqs0uMsYufFXSE4q6cA6Ty1fwZuMk4BJRHfiGSna59F1otnxiDelwhN4fEwmBtIymmF0ZqXHnpSigr2ps9Cg==",
|
"integrity": "sha512-Mvf3gJFzZCkhjY2Y/Fx9z1m3dxbza0uI9H1CbNZm/jSHCojzJhQ0R7bByrlFJINnMzz/gPulpoFFGymNwrsMcw==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@emotion/is-prop-valid": "1.2.1",
|
"@emotion/is-prop-valid": "1.2.2",
|
||||||
"@emotion/unitless": "0.8.1",
|
"@emotion/unitless": "0.8.1",
|
||||||
"@types/stylis": "4.2.0",
|
"@types/stylis": "4.2.5",
|
||||||
"css-to-react-native": "3.2.0",
|
"css-to-react-native": "3.2.0",
|
||||||
"csstype": "3.1.2",
|
"csstype": "3.1.3",
|
||||||
"postcss": "8.4.31",
|
"postcss": "8.4.49",
|
||||||
"shallowequal": "1.1.0",
|
"shallowequal": "1.1.0",
|
||||||
"stylis": "4.3.1",
|
"stylis": "4.3.2",
|
||||||
"tslib": "2.5.0"
|
"tslib": "2.6.2"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 16"
|
"node": ">= 16"
|
||||||
@@ -1721,9 +1771,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/stylis": {
|
"node_modules/stylis": {
|
||||||
"version": "4.3.1",
|
"version": "4.3.2",
|
||||||
"resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.2.tgz",
|
||||||
"integrity": "sha512-EQepAV+wMsIaGVGX1RECzgrcqRRU/0sYOHkeLsZ3fzHaHXZy4DaOOX0vOlGQdlsjkh3mFHAIlVimpwAs4dslyQ=="
|
"integrity": "sha512-bhtUjWd/z6ltJiQwg0dUfxEJ+W+jdqQd8TbWLWyeIJHlnsqmGLRFFd8e5mA0AZi/zx90smXRlN66YMTcaSFifg==",
|
||||||
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/supports-color": {
|
"node_modules/supports-color": {
|
||||||
"version": "5.5.0",
|
"version": "5.5.0",
|
||||||
@@ -1748,9 +1799,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/tslib": {
|
"node_modules/tslib": {
|
||||||
"version": "2.5.0",
|
"version": "2.6.2",
|
||||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
|
||||||
"integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg=="
|
"integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==",
|
||||||
|
"license": "0BSD"
|
||||||
},
|
},
|
||||||
"node_modules/typed-array-buffer": {
|
"node_modules/typed-array-buffer": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
@@ -1814,9 +1866,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/typescript": {
|
"node_modules/typescript": {
|
||||||
"version": "5.2.2",
|
"version": "5.8.3",
|
||||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz",
|
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz",
|
||||||
"integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==",
|
"integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==",
|
||||||
|
"license": "Apache-2.0",
|
||||||
"bin": {
|
"bin": {
|
||||||
"tsc": "bin/tsc",
|
"tsc": "bin/tsc",
|
||||||
"tsserver": "bin/tsserver"
|
"tsserver": "bin/tsserver"
|
||||||
|
|||||||
18
package.json
18
package.json
@@ -20,16 +20,16 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/chrome": "^0.0.251",
|
"@types/chrome": "^0.0.251",
|
||||||
"@types/lodash.uniq": "^4.5.9",
|
"@types/lodash.uniq": "^4.5.9",
|
||||||
"@types/react": "^18.2.37",
|
"@types/react": "^18.3.23",
|
||||||
"@types/react-dom": "^18.2.15",
|
"@types/react-dom": "^18.3.7",
|
||||||
"esbuild": "^0.19.5",
|
"esbuild": "^0.19.12",
|
||||||
"fuse.js": "^7.0.0",
|
"fuse.js": "^7.1.0",
|
||||||
"lodash.uniq": "^4.5.0",
|
"lodash.uniq": "^4.5.0",
|
||||||
"npm-run-all": "^4.1.5",
|
"npm-run-all": "^4.1.5",
|
||||||
"react": "^18.2.0",
|
"react": "^18.3.1",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.3.1",
|
||||||
"react-hotkeys-hook": "^4.4.1",
|
"react-hotkeys-hook": "^4.6.2",
|
||||||
"styled-components": "^6.1.9",
|
"styled-components": "^6.1.18",
|
||||||
"typescript": "^5.2.2"
|
"typescript": "^5.8.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import type { Tab } from "../types";
|
||||||
|
|
||||||
declare const browser: typeof chrome;
|
declare const browser: typeof chrome;
|
||||||
|
|
||||||
// tabSwitches is a stack of all tab activations. every time a tab becomes
|
// tabSwitches is a stack of all tab activations. every time a tab becomes
|
||||||
@@ -35,19 +37,39 @@ setInterval(() => {
|
|||||||
tabSwitches = uniq(tabSwitches);
|
tabSwitches = uniq(tabSwitches);
|
||||||
}, 1000);
|
}, 1000);
|
||||||
|
|
||||||
async function listTabs(): Promise<chrome.tabs.Tab[]> {
|
async function listTabs(): Promise<Tab[]> {
|
||||||
const _tabs = await browser.tabs.query({});
|
const [tabs, groups] = await Promise.all([
|
||||||
|
browser.tabs.query({}).then(
|
||||||
// filter out file:///... things, safari does not really have
|
// filter out file:///... things, safari does not really have
|
||||||
// safari://... things like chrome
|
// safari://... things like chrome
|
||||||
const tabs = _tabs.filter((t) => t.url || t.title);
|
(allTabs) => allTabs.filter((t) => t.url || t.title)
|
||||||
|
),
|
||||||
|
browser.tabGroups
|
||||||
|
.query({})
|
||||||
|
.then((groups): Map<number, chrome.tabGroups.TabGroup> => {
|
||||||
|
return new Map(groups.map((g) => [g.id, g]));
|
||||||
|
}),
|
||||||
|
]);
|
||||||
|
|
||||||
const hit = new Map<number, boolean>(
|
const hit = new Map<number, boolean>(
|
||||||
tabs.filter((t) => !!t.id).map((t) => [t.id!, false])
|
tabs.filter((t) => !!t.id).map((t) => [t.id!, false])
|
||||||
);
|
);
|
||||||
const tabsById = new Map<number, chrome.tabs.Tab>(
|
const tabsById = new Map<number, Tab>(
|
||||||
tabs.filter((t) => !!t.id).map((t) => [t.id!, t])
|
tabs
|
||||||
|
.filter((t) => !!t.id)
|
||||||
|
.map((t) => {
|
||||||
|
const group = t.groupId > 0 ? groups.get(t.groupId) : undefined;
|
||||||
|
return [
|
||||||
|
t.id!,
|
||||||
|
{
|
||||||
|
...t,
|
||||||
|
group,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
})
|
||||||
);
|
);
|
||||||
const resultTabs = [];
|
|
||||||
|
const resultTabs: Tab[] = [];
|
||||||
for (let tabId of tabSwitches.slice(1)) {
|
for (let tabId of tabSwitches.slice(1)) {
|
||||||
if (hit.get(tabId)) {
|
if (hit.get(tabId)) {
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import React, {
|
|||||||
import ReactDOM from "react-dom/client";
|
import ReactDOM from "react-dom/client";
|
||||||
import { useHotkeys } from "react-hotkeys-hook";
|
import { useHotkeys } from "react-hotkeys-hook";
|
||||||
import { styled } from "styled-components";
|
import { styled } from "styled-components";
|
||||||
|
import type { Tab } from "../types";
|
||||||
import "./scrollIntoViewIfNeededPolyfill";
|
import "./scrollIntoViewIfNeededPolyfill";
|
||||||
|
|
||||||
function t(
|
function t(
|
||||||
@@ -31,8 +32,8 @@ function hostname(url: string): string {
|
|||||||
const browser = chrome;
|
const browser = chrome;
|
||||||
|
|
||||||
interface BackgroundPage {
|
interface BackgroundPage {
|
||||||
listTabs(): Promise<chrome.tabs.Tab[]>;
|
listTabs(): Promise<Tab[]>;
|
||||||
closeTab(tabID: number): Promise<chrome.tabs.Tab[]>;
|
closeTab(tabID: number): Promise<Tab[]>;
|
||||||
}
|
}
|
||||||
|
|
||||||
function useBackgroundPage(): BackgroundPage {
|
function useBackgroundPage(): BackgroundPage {
|
||||||
@@ -76,7 +77,7 @@ function useBackgroundPage(): BackgroundPage {
|
|||||||
waiter.current.set(id, {
|
waiter.current.set(id, {
|
||||||
reject,
|
reject,
|
||||||
resolve(value) {
|
resolve(value) {
|
||||||
resolve(value as chrome.tabs.Tab[]);
|
resolve(value as Tab[]);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
port.current.postMessage({ rpc: "listTabs", id });
|
port.current.postMessage({ rpc: "listTabs", id });
|
||||||
@@ -88,7 +89,7 @@ function useBackgroundPage(): BackgroundPage {
|
|||||||
waiter.current.set(id, {
|
waiter.current.set(id, {
|
||||||
reject,
|
reject,
|
||||||
resolve(value) {
|
resolve(value) {
|
||||||
resolve(value as chrome.tabs.Tab[]);
|
resolve(value as Tab[]);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
port.current.postMessage({ rpc: "closeTab", id, args: { tabID } });
|
port.current.postMessage({ rpc: "closeTab", id, args: { tabID } });
|
||||||
@@ -147,41 +148,11 @@ const HighlightMatches: FunctionComponent<{
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
// // <big_sigh> ...
|
function faviconURL(t: Tab): string | undefined {
|
||||||
// function faviconsWork(tabURL: string, size: number): Promise<boolean> {
|
|
||||||
// return new Promise((resolve) => {
|
|
||||||
// const hiddenDiv = document.createElement("div", {});
|
|
||||||
// hiddenDiv.setAttribute("style", "display:none;");
|
|
||||||
// const testImg = document.createElement("img");
|
|
||||||
// testImg.src = faviconURL({ url: tabURL } as chrome.tabs.Tab, 32)!;
|
|
||||||
// testImg.onerror = () => {
|
|
||||||
// document.body.removeChild(hiddenDiv);
|
|
||||||
// resolve(false);
|
|
||||||
// };
|
|
||||||
// testImg.onload = () => {
|
|
||||||
// document.body.removeChild(hiddenDiv);
|
|
||||||
// resolve(true);
|
|
||||||
// };
|
|
||||||
// hiddenDiv.appendChild(testImg);
|
|
||||||
// document.body.appendChild(hiddenDiv);
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
|
|
||||||
function faviconURL(t: chrome.tabs.Tab, size: number): string | undefined {
|
|
||||||
return (
|
return (
|
||||||
t.favIconUrl ??
|
t.favIconUrl ??
|
||||||
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII="
|
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII="
|
||||||
);
|
);
|
||||||
// if (t.favIconUrl) {
|
|
||||||
// return t.favIconUrl;
|
|
||||||
// }
|
|
||||||
// if (!t.url) {
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
// const url = new URL(browser.runtime.getURL("/_favicon/"));
|
|
||||||
// url.searchParams.set("pageUrl", t.url);
|
|
||||||
// url.searchParams.set("size", `${size}`);
|
|
||||||
// return url.toString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const prefersDarkMode = (): boolean => {
|
const prefersDarkMode = (): boolean => {
|
||||||
@@ -261,6 +232,9 @@ const TabItemFavicon = styled.div<{ $dark: boolean }>`
|
|||||||
padding: 7px;
|
padding: 7px;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
`;
|
`;
|
||||||
|
const TabItemCloseBox = styled.div`
|
||||||
|
cursor: pointer;
|
||||||
|
`;
|
||||||
const TabItemMain = styled.div`
|
const TabItemMain = styled.div`
|
||||||
width: ${TAB_ITEM_MAIN_WIDTH}px;
|
width: ${TAB_ITEM_MAIN_WIDTH}px;
|
||||||
`;
|
`;
|
||||||
@@ -272,12 +246,71 @@ const TabItemMainTitle = styled.div<{ $dark: boolean }>`
|
|||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
`;
|
`;
|
||||||
const TabItemMainHostname = styled.div<{ $dark: boolean }>`
|
const TabItemMainHostname = styled.div<{ $dark: boolean }>`
|
||||||
|
margin-top: 3px;
|
||||||
color: ${(props) => (props.$dark ? "#a9a9a9" : "#6e6e6e")};
|
color: ${(props) => (props.$dark ? "#a9a9a9" : "#6e6e6e")};
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
type ColorSet<C extends string> = `${C}` | `${C}-invert` | `${C}-pale`;
|
||||||
|
|
||||||
|
const tabGroupColors: {
|
||||||
|
[K in ColorSet<chrome.tabGroups.ColorEnum>]: string;
|
||||||
|
} = {
|
||||||
|
blue: "oklch(48% 0.2 260)",
|
||||||
|
"blue-invert": "oklch(83% 0.17 260)",
|
||||||
|
"blue-pale": "oklch(97% 0.05 260)",
|
||||||
|
|
||||||
|
purple: "oklch(48% 0.2 315)",
|
||||||
|
"purple-invert": "oklch(83% 0.14 315)",
|
||||||
|
"purple-pale": "oklch(97% 0.05 315)",
|
||||||
|
|
||||||
|
cyan: "oklch(48% 0.2 205)",
|
||||||
|
"cyan-invert": "oklch(83% 0.11 205)",
|
||||||
|
"cyan-pale": "oklch(97% 0.05 205)",
|
||||||
|
|
||||||
|
orange: "oklch(48% 0.2 50)",
|
||||||
|
"orange-invert": "oklch(86% 0.14 50)",
|
||||||
|
"orange-pale": "oklch(97% 0.05 50)",
|
||||||
|
|
||||||
|
yellow: "oklch(51% 0.23 90)",
|
||||||
|
"yellow-invert": "oklch(86% 0.14 90)",
|
||||||
|
"yellow-pale": "oklch(97% 0.05 90)",
|
||||||
|
|
||||||
|
pink: "oklch(48% 0.2 360)",
|
||||||
|
"pink-invert": "oklch(83% 0.14 360)",
|
||||||
|
"pink-pale": "oklch(97% 0.05 360)",
|
||||||
|
|
||||||
|
green: "oklch(48% 0.2 145)",
|
||||||
|
"green-invert": "oklch(83% 0.14 145)",
|
||||||
|
"green-pale": "oklch(97% 0.05 145)",
|
||||||
|
|
||||||
|
red: "oklch(48% 0.2 15)",
|
||||||
|
"red-invert": "oklch(83% 0.14 15)",
|
||||||
|
"red-pale": "oklch(97% 0.05 15)",
|
||||||
|
|
||||||
|
grey: "#5e6a77",
|
||||||
|
"grey-invert": "#99a6b4",
|
||||||
|
"grey-pale": "#f2f9ff",
|
||||||
|
};
|
||||||
|
|
||||||
|
const TabItemGroupPill = styled.span<{
|
||||||
|
$dark: boolean;
|
||||||
|
$color: chrome.tabGroups.ColorEnum;
|
||||||
|
}>`
|
||||||
|
background-color: ${(props) =>
|
||||||
|
props.$dark
|
||||||
|
? tabGroupColors[`${props.$color}-invert`]
|
||||||
|
: tabGroupColors[props.$color]};
|
||||||
|
color: ${(props) =>
|
||||||
|
props.$dark ? `#15141a` : tabGroupColors[`${props.$color}-pale`]};
|
||||||
|
font-weight: 500;
|
||||||
|
padding: 3px 5px;
|
||||||
|
border-radius: 4px;
|
||||||
|
display: inline-block;
|
||||||
|
`;
|
||||||
|
|
||||||
const SearchContainer = styled.div`
|
const SearchContainer = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
width: ${SEARCH_CONTAINER_WIDTH}px;
|
width: ${SEARCH_CONTAINER_WIDTH}px;
|
||||||
@@ -298,24 +331,79 @@ const SearchInput = styled.input`
|
|||||||
font-size: 1.2em;
|
font-size: 1.2em;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
type searchField = {
|
||||||
|
aliases?: string[];
|
||||||
|
filterValues: (value: string | null) => boolean;
|
||||||
|
evaluate: (t: Tab, value: string | null) => boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
const searchFields: Record<string, searchField> = {
|
||||||
|
sys: {
|
||||||
|
filterValues(value) {
|
||||||
|
return ["true", "false"].includes(value?.toLowerCase() ?? "");
|
||||||
|
},
|
||||||
|
evaluate(t, value) {
|
||||||
|
if (!t.url) {
|
||||||
|
return value === "true";
|
||||||
|
}
|
||||||
|
const ishttp = !!t.url.match(/^https?:\/\//i);
|
||||||
|
return ishttp !== (value === "true");
|
||||||
|
},
|
||||||
|
},
|
||||||
|
pinned: {
|
||||||
|
filterValues(value) {
|
||||||
|
return ["true", "false"].includes(value?.toLowerCase() ?? "");
|
||||||
|
},
|
||||||
|
evaluate(t, value) {
|
||||||
|
return t.pinned === (value === "true");
|
||||||
|
},
|
||||||
|
},
|
||||||
|
hostname: {
|
||||||
|
aliases: ["domain"],
|
||||||
|
filterValues(value) {
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
evaluate(t, value) {
|
||||||
|
if (!t.url) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return hostname(t.url).includes(value ?? "");
|
||||||
|
},
|
||||||
|
},
|
||||||
|
} as const;
|
||||||
|
|
||||||
|
function getSearchField(key: string): searchField | null {
|
||||||
|
return key in searchFields
|
||||||
|
? searchFields[key]
|
||||||
|
: Object.values(searchFields).find((sf) => {
|
||||||
|
return sf.aliases?.includes(key) ?? false;
|
||||||
|
}) ?? null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function structuredQuery(query: string): Map<string, string | null> {
|
||||||
|
return new Map<string, string | null>(
|
||||||
|
query
|
||||||
|
.split(/\s+/g)
|
||||||
|
.map((pair): [string, string | null] => {
|
||||||
|
const [key, value] = pair.split(":", 2);
|
||||||
|
return [key, value ?? null];
|
||||||
|
})
|
||||||
|
.filter(([key, value]) => {
|
||||||
|
const sf = getSearchField(key);
|
||||||
|
if (!sf) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return sf.filterValues(value);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const Popup: FunctionComponent = () => {
|
const Popup: FunctionComponent = () => {
|
||||||
const darkMode = useDarkMode();
|
const darkMode = useDarkMode();
|
||||||
const [tabSelector, setTabSelector] = useState(0);
|
const [tabSelector, setTabSelector] = useState(0);
|
||||||
const [tabs, setTabs] = useState<chrome.tabs.Tab[]>([]);
|
const [tabs, setTabs] = useState<Tab[]>([]);
|
||||||
const [searchQuery, setSearchQuery] = useState("");
|
const [searchQuery, setSearchQuery] = useState("");
|
||||||
|
|
||||||
// const FAVICON_NOT_SUPPORTED = 0;
|
|
||||||
// const FAVICON_SUPPORTED_VIA_EXT_URL = 1;
|
|
||||||
// const FAVICON_SUPPORTED_VIA_TAB_DATA = 2;
|
|
||||||
// const [enableFavicons, setEnabledFavicons] = useState(FAVICON_NOT_SUPPORTED);
|
|
||||||
// useEffect(() => {
|
|
||||||
// faviconsWork("https://www.google.com", 32).then((ok) => {
|
|
||||||
// if (enableFavicons === 0) {
|
|
||||||
// setEnabledFavicons(FAVICON_SUPPORTED_VIA_EXT_URL);
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// }, []);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (tabs.length === 0) {
|
if (tabs.length === 0) {
|
||||||
return;
|
return;
|
||||||
@@ -327,7 +415,21 @@ const Popup: FunctionComponent = () => {
|
|||||||
}, [setTabSelector, searchQuery]);
|
}, [setTabSelector, searchQuery]);
|
||||||
const searchIndex = useMemo(() => {
|
const searchIndex = useMemo(() => {
|
||||||
const result = new Fuse(tabs, {
|
const result = new Fuse(tabs, {
|
||||||
keys: ["title", "url"],
|
keys: [
|
||||||
|
"title",
|
||||||
|
{
|
||||||
|
name: "hostname",
|
||||||
|
getFn(obj) {
|
||||||
|
return obj.url ? hostname(obj.url) : "";
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "group",
|
||||||
|
getFn(obj) {
|
||||||
|
return obj.group?.title ?? "";
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
includeMatches: true,
|
includeMatches: true,
|
||||||
});
|
});
|
||||||
return result;
|
return result;
|
||||||
@@ -335,7 +437,25 @@ const Popup: FunctionComponent = () => {
|
|||||||
const searchResults = useMemo(() => {
|
const searchResults = useMemo(() => {
|
||||||
if (!searchQuery) {
|
if (!searchQuery) {
|
||||||
return tabs.map(
|
return tabs.map(
|
||||||
(t, i): FuseResult<chrome.tabs.Tab> => ({
|
(t, i): FuseResult<Tab> => ({
|
||||||
|
item: t,
|
||||||
|
refIndex: i,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
const sq = structuredQuery(searchQuery);
|
||||||
|
if (sq.size > 0) {
|
||||||
|
return tabs
|
||||||
|
.filter((tab) => {
|
||||||
|
for (let [key, value] of sq.entries()) {
|
||||||
|
if (!getSearchField(key)!.evaluate(tab, value)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
})
|
||||||
|
.map(
|
||||||
|
(t, i): FuseResult<Tab> => ({
|
||||||
item: t,
|
item: t,
|
||||||
refIndex: i,
|
refIndex: i,
|
||||||
})
|
})
|
||||||
@@ -409,7 +529,14 @@ const Popup: FunctionComponent = () => {
|
|||||||
}, [selectedTabEle.current]);
|
}, [selectedTabEle.current]);
|
||||||
|
|
||||||
const [tabHover, setTabHover] = useState<number | null>(null);
|
const [tabHover, setTabHover] = useState<number | null>(null);
|
||||||
|
const inputRef = useRef<HTMLInputElement | null>(null);
|
||||||
|
useEffect(() => {
|
||||||
|
requestIdleCallback(() => {
|
||||||
|
// this is more reliable than autoFocus attribute. sometimes autoFocus
|
||||||
|
// would let the popup open and then input would not be focused.
|
||||||
|
inputRef.current?.focus();
|
||||||
|
});
|
||||||
|
}, [inputRef.current]);
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<SearchContainer>
|
<SearchContainer>
|
||||||
@@ -428,8 +555,8 @@ const Popup: FunctionComponent = () => {
|
|||||||
</SearchIconLeftContainer>
|
</SearchIconLeftContainer>
|
||||||
<SearchInputRightContainer>
|
<SearchInputRightContainer>
|
||||||
<SearchInput
|
<SearchInput
|
||||||
|
ref={inputRef}
|
||||||
type="text"
|
type="text"
|
||||||
autoFocus
|
|
||||||
placeholder={t("ui_search_tabs")}
|
placeholder={t("ui_search_tabs")}
|
||||||
value={searchQuery}
|
value={searchQuery}
|
||||||
onKeyDown={(e) => {
|
onKeyDown={(e) => {
|
||||||
@@ -458,7 +585,7 @@ const Popup: FunctionComponent = () => {
|
|||||||
<TabListEmpty>No Results Found</TabListEmpty>
|
<TabListEmpty>No Results Found</TabListEmpty>
|
||||||
) : null}
|
) : null}
|
||||||
{searchResults.map((t, i) => {
|
{searchResults.map((t, i) => {
|
||||||
const favicURL = faviconURL(t.item, 32);
|
const favicURL = faviconURL(t.item);
|
||||||
const showCloseAction = tabHover === t.item.id! && !t.item.pinned;
|
const showCloseAction = tabHover === t.item.id! && !t.item.pinned;
|
||||||
return (
|
return (
|
||||||
<TabItem
|
<TabItem
|
||||||
@@ -480,7 +607,7 @@ const Popup: FunctionComponent = () => {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{showCloseAction ? (
|
{showCloseAction ? (
|
||||||
<div
|
<TabItemCloseBox
|
||||||
title="Close Tab"
|
title="Close Tab"
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
@@ -500,7 +627,7 @@ const Popup: FunctionComponent = () => {
|
|||||||
>
|
>
|
||||||
<path d="M12 0c-6.627 0-12 5.373-12 12s5.373 12 12 12 12-5.373 12-12-5.373-12-12-12zm4.151 17.943l-4.143-4.102-4.117 4.159-1.833-1.833 4.104-4.157-4.162-4.119 1.833-1.833 4.155 4.102 4.106-4.16 1.849 1.849-4.1 4.141 4.157 4.104-1.849 1.849z" />
|
<path d="M12 0c-6.627 0-12 5.373-12 12s5.373 12 12 12 12-5.373 12-12-5.373-12-12-12zm4.151 17.943l-4.143-4.102-4.117 4.159-1.833-1.833 4.104-4.157-4.162-4.119 1.833-1.833 4.155 4.102 4.106-4.16 1.849 1.849-4.1 4.141 4.157 4.104-1.849 1.849z" />
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</TabItemCloseBox>
|
||||||
) : (
|
) : (
|
||||||
<img width={16} height={16} src={favicURL} />
|
<img width={16} height={16} src={favicURL} />
|
||||||
)}
|
)}
|
||||||
@@ -514,6 +641,17 @@ const Popup: FunctionComponent = () => {
|
|||||||
</TabItemMainTitle>
|
</TabItemMainTitle>
|
||||||
<TabItemMainHostname $dark={darkMode}>
|
<TabItemMainHostname $dark={darkMode}>
|
||||||
{t.item.url ? hostname(t.item.url) : ""}
|
{t.item.url ? hostname(t.item.url) : ""}
|
||||||
|
{t.item.group ? (
|
||||||
|
<>
|
||||||
|
|
|
||||||
|
<TabItemGroupPill
|
||||||
|
$dark={darkMode}
|
||||||
|
$color={t.item.group.color}
|
||||||
|
>
|
||||||
|
{t.item.group.title}
|
||||||
|
</TabItemGroupPill>
|
||||||
|
</>
|
||||||
|
) : null}
|
||||||
</TabItemMainHostname>
|
</TabItemMainHostname>
|
||||||
</TabItemMain>
|
</TabItemMain>
|
||||||
</TabItem>
|
</TabItem>
|
||||||
|
|||||||
3
src/types.ts
Normal file
3
src/types.ts
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
export type Tab = chrome.tabs.Tab & {
|
||||||
|
group?: chrome.tabGroups.TabGroup;
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user