├── .github └── FUNDING.yml ├── CONTRIBUTING.md ├── LICENSE.md ├── README.md ├── bin └── update.json ├── dist └── Iridium.xpi ├── src ├── chrome │ ├── _locales │ │ └── en_US │ │ │ └── messages.json │ ├── css │ │ ├── content-script.css │ │ └── options.css │ ├── font │ │ ├── LICENSE.txt │ │ ├── Roboto-Black.ttf │ │ ├── Roboto-BlackItalic.ttf │ │ ├── Roboto-Bold.ttf │ │ ├── Roboto-BoldItalic.ttf │ │ ├── Roboto-Italic.ttf │ │ ├── Roboto-Light.ttf │ │ ├── Roboto-LightItalic.ttf │ │ ├── Roboto-Medium.ttf │ │ ├── Roboto-MediumItalic.ttf │ │ ├── Roboto-Regular.ttf │ │ ├── Roboto-Thin.ttf │ │ └── Roboto-ThinItalic.ttf │ ├── html │ │ └── options.html │ ├── icons │ │ ├── 128.png │ │ ├── 144.png │ │ ├── 16.png │ │ ├── 32.png │ │ ├── 48.png │ │ ├── 64.png │ │ └── favicon.ico │ ├── img │ │ └── iridium.svg │ ├── js │ │ ├── background-inject.js │ │ ├── background.js │ │ ├── chrome-wrapper.js │ │ ├── content-script.js │ │ ├── options.js │ │ ├── service-worker.js │ │ └── setting-data.js │ └── manifest.json └── firefox │ ├── _locales │ └── en_US │ │ └── messages.json │ ├── css │ ├── content-script.css │ └── options.css │ ├── font │ ├── LICENSE.txt │ ├── Roboto-Black.ttf │ ├── Roboto-BlackItalic.ttf │ ├── Roboto-Bold.ttf │ ├── Roboto-BoldItalic.ttf │ ├── Roboto-Italic.ttf │ ├── Roboto-Light.ttf │ ├── Roboto-LightItalic.ttf │ ├── Roboto-Medium.ttf │ ├── Roboto-MediumItalic.ttf │ ├── Roboto-Regular.ttf │ ├── Roboto-Thin.ttf │ └── Roboto-ThinItalic.ttf │ ├── html │ └── options.html │ ├── icons │ ├── 128.png │ ├── 144.png │ ├── 16.png │ ├── 32.png │ ├── 48.png │ ├── 64.png │ └── favicon.ico │ ├── img │ └── iridium.svg │ ├── js │ ├── background-inject.js │ ├── background.js │ ├── content-script.js │ ├── options.js │ └── setting-data.js │ └── manifest.json └── types └── chrome-types ├── LICENSE ├── README.md ├── _all.d.ts ├── index.d.ts └── package.json /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | patreon: particle 2 | #open_collective: open_collective_username 3 | #ko_fi: ko_fi_username 4 | #tidelift: tidelift_package_name 5 | #community_bridge: community_bridge_username 6 | #liberapay: liberapay_username 7 | #issuehunt: issuehunt_username 8 | #otechie: otechie_username 9 | #custom: ["custom_url.com", “another_custom_url.com”] -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | #### Feature request: 2 | - If you want to make a feature request please open a new issue for each feature 3 | 4 | #### Bug/problem report: 5 | - Follow the instructions for reporting a bug here: https://github.com/ParticleCore/Iridium/wiki/Report-a-bug 6 | 7 | --- 8 | 9 | ### Contributing to source code 10 | 11 | While help is appreciated, source code submissions will not be accepted. If users really want to implement modifications please create your own forks, don't submit pull requests. 12 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Contact for permissions other than the use of the software and its contents for non-comercial 2 | personal purposes, such as, and not limited to: 3 | 4 | - Use of the software for its intended purpose 5 | - Use of the source code for learning and teaching purposes 6 | - Use of the software and its source code for sharing without unauthorized third party modifications 7 | with included easily visible linkbacks directing to the source of the original file(s) location(s) or main directory 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Iridium 2 | [![current version](https://img.shields.io/github/release/ParticleCore/Iridium/all.svg)](https://github.com/ParticleCore/Iridium/releases/latest) [![firefox](https://img.shields.io/amo/users/particle-iridium?logo=firefoxbrowser&logoColor=white&label=%20)](https://addons.mozilla.org/firefox/addon/particle-iridium/) [![chrome](https://img.shields.io/chrome-web-store/users/gbjmgndncjkjfcnpfhgidhbgokofegbl?logo=googlechrome&logoColor=white&label=%20)](https://chromewebstore.google.com/detail/gbjmgndncjkjfcnpfhgidhbgokofegbl) 3 | 4 | **[Download](https://github.com/ParticleCore/Iridium/wiki/Download) | [Report a problem](https://github.com/ParticleCore/Iridium/wiki/Report-a-bug) | [Donate](https://github.com/ParticleCore/Iridium/wiki/Donate)** 5 | 6 | # Iridium v2.0 is out and working again 7 | The extension is now available for download and you can find it on Firefox AMO Store, Chrome Web Store, or the self-hosted option which is updated faster. You can find more information in the [download](https://github.com/ParticleCore/Iridium/wiki/Download) instructions. 8 | 9 | If you have any issue with the extension please follow the [instructions](https://github.com/ParticleCore/Iridium/wiki/Report-a-bug) before opening a new bug report. 10 | 11 | A list of available features will be eventually updated and linked here, but for now check the projects for a draft of features implemented in each version update, as well as features planned for future versions. 12 | 13 | This readme will be improved over time when possible. 14 | -------------------------------------------------------------------------------- /bin/update.json: -------------------------------------------------------------------------------- 1 | { 2 | "addons": { 3 | "unlisted-iridium@particlecore.github.io": { 4 | "updates": [ 5 | { 6 | "version": "2.1.2", 7 | "update_link": "https://github.com/ParticleCore/Iridium/raw/master/dist/Iridium.xpi", 8 | "applications": { 9 | "gecko": { 10 | "strict_min_version": "110.0" 11 | } 12 | } 13 | } 14 | ] 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /dist/Iridium.xpi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ParticleCore/Iridium/be0acb55146aac60c34eef3fe22f3dda407aa2fa/dist/Iridium.xpi -------------------------------------------------------------------------------- /src/chrome/_locales/en_US/messages.json: -------------------------------------------------------------------------------- 1 | { 2 | "locale_id": { 3 | "message": "English (US)" 4 | }, 5 | "page_title": { 6 | "message": "Iridium" 7 | } 8 | } -------------------------------------------------------------------------------- /src/chrome/css/content-script.css: -------------------------------------------------------------------------------- 1 | /* ini | autoplay */ 2 | #movie_player.unstarted-mode:is(.playing-mode, .paused-mode):not(.buffering-mode, .ytp-player-minimized) > *:not(.ytp-cued-thumbnail-overlay) { 3 | display: none; 4 | } 5 | /* end | autoplay */ 6 | 7 | /* ini | autoplay channel trailer */ 8 | #c4-player.unstarted-mode:is(.playing-mode, .paused-mode):not(.buffering-mode) > *:not(.ytp-cued-thumbnail-overlay) { 9 | display: none; 10 | } 11 | /* end | autoplay channel trailer */ 12 | 13 | /* ini | video focus */ 14 | html #masthead-container, 15 | html #secondary, 16 | html #below { 17 | transition-property: opacity !important; 18 | transition-duration: 0.8s !important;; 19 | transition-timing-function: ease !important;; 20 | transition-delay: 0.25s !important;; 21 | } 22 | html[dim] #masthead-container:not(:hover), 23 | html[dim] #secondary:not(:hover), 24 | html[dim] #below:not(:hover) { 25 | opacity: 0.1; 26 | } 27 | /* end | video focus */ 28 | 29 | /* ini | iridium icon */ 30 | html[dark] .iridium-options yt-icon { 31 | background: #fff; 32 | } 33 | html .iridium-options:hover yt-icon { 34 | background: radial-gradient(circle at 0% 150%, #0ff 35%, #f0f 75%); 35 | } 36 | .iridium-options yt-icon { 37 | mask-image: url('data:image/svg+xml,'); 38 | background: #030303; 39 | } 40 | /* end | iridium icon */ 41 | 42 | /* ini | reverse playlist */ 43 | ytd-toggle-button-renderer:has([aria-label="reversePlaylistButton"]) { 44 | margin-left: 0 !important; 45 | } 46 | html[dark] [aria-label="reversePlaylistButton"] yt-icon { 47 | background: #f1f1f1; 48 | } 49 | [aria-label="reversePlaylistButton"] yt-icon { 50 | background: #0f0f0f; 51 | } 52 | [aria-label="reversePlaylistButton"] yt-icon { 53 | mask-image: url('data:image/svg+xml,'); 54 | } 55 | [aria-label="reversePlaylistButton"][aria-pressed="true"] yt-icon { 56 | mask-image: url('data:image/svg+xml,'); 57 | } 58 | /* end | reverse playlist */ 59 | 60 | /* ini | full titles */ 61 | html.iridium-full-titles #video-title.ytd-video-renderer, 62 | html.iridium-full-titles #video-title.ytd-compact-video-renderer, 63 | html.iridium-full-titles #video-title.ytd-reel-item-renderer, 64 | html.iridium-full-titles #video-title.ytd-rich-grid-media { 65 | max-height: unset; 66 | -webkit-line-clamp: unset; 67 | } 68 | /* end | full titles */ 69 | 70 | /* ini | super theater */ 71 | html[super-theater] #masthead-container.ytd-app:has( > [theater][is-watch-page]) #masthead { 72 | transform: translateY(-100%); 73 | transition: transform .5s ease-out !important; 74 | } 75 | html[super-theater] #masthead-container.ytd-app:has( > [theater][is-watch-page]):hover #masthead { 76 | transform: translateY(0); 77 | } 78 | html[super-theater] ytd-watch-flexy[full-bleed-player]:not([hidden]) #full-bleed-container.ytd-watch-flexy, 79 | html[super-theater] ytd-watch-grid[full-bleed-player]:not([hidden]) #player-full-bleed-container.ytd-watch-grid { 80 | max-height: calc(100vh); 81 | height: calc(100vh); 82 | min-height: unset; 83 | } 84 | html[super-theater] #page-manager.ytd-app:has( > [theater]:not([hidden])) { 85 | margin-top: 0; 86 | } 87 | html[super-theater] #page-manager.ytd-app:has( > [theater]:not([hidden])) ytd-live-chat-frame { 88 | top: 0 !important; 89 | } 90 | html[super-theater] #player-full-bleed-container { 91 | display: flex; 92 | flex-direction: row; 93 | } 94 | html[super-theater] #player-full-bleed-container #player-container { 95 | position: relative; 96 | flex: 1; 97 | } 98 | html[super-theater]:not([super-theater]) #masthead-container.ytd-app, 99 | html[super-theater][super-theater] #masthead-container.ytd-app:not(:has( > [is-watch-page])) { 100 | width: 100% !important; 101 | } 102 | html[super-theater] #page-manager.ytd-app:has( > [theater]:not([hidden])) #chat-container { 103 | position: relative; 104 | } 105 | html[super-theater] #page-manager.ytd-app:has( > [theater]:not([hidden])) ytd-live-chat-frame { 106 | height: 100% !important; 107 | min-height: unset !important; 108 | top: unset !important; 109 | } 110 | /* end | super theater */ 111 | 112 | /* ini | super theater scrollbar */ 113 | html[super-theater][super-theater-scrollbar]:has( ytd-watch-flexy[theater]:not([hidden])) { 114 | scrollbar-width: none; 115 | } 116 | /* end | super theater scrollbar */ 117 | 118 | /* ini | hide end screen cards */ 119 | .iridium-hide-end-screen-cards #movie_player:hover .ytp-ce-element:not(:hover) { 120 | opacity: 0; 121 | } 122 | /* end | hide end screen cards */ 123 | 124 | /* ini | scroll volume */ 125 | #iridium-scroll-volume-level-container { 126 | text-align: center; 127 | position: absolute; 128 | left: 0; 129 | right: 0; 130 | top: 10%; 131 | z-index: 19; 132 | } 133 | #iridium-scroll-volume-level { 134 | display: inline-block; 135 | padding: 10px 20px; 136 | font-size: 175%; 137 | background: rgba(0, 0, 0, .5); 138 | pointer-events: none; 139 | border-radius: 3px; 140 | } 141 | /* end | scroll volume */ 142 | 143 | /* ini | player tools */ 144 | #iridium-player-tools { 145 | display: flex; 146 | align-items: center; 147 | justify-content: center; 148 | font-size: 0; 149 | position: absolute; 150 | top: 0; 151 | right: 0; 152 | bottom: 0; 153 | } 154 | #bottom-grid #iridium-player-tools { 155 | position: unset; 156 | margin-left: auto; 157 | } 158 | #iridium-player-tools > div { 159 | cursor: pointer; 160 | width: 36px; 161 | height: 36px; 162 | justify-content: center; 163 | display: flex; 164 | align-items: center; 165 | fill: var(--yt-spec-text-primary); 166 | position: relative; 167 | } 168 | #iridium-player-tools > div:hover { 169 | background-color: var(--yt-spec-10-percent-layer); 170 | border-radius: 18px; 171 | } 172 | #iridium-player-tools > div > svg { 173 | pointer-events: none; 174 | user-select: none; 175 | } 176 | #iridium-autoplay-shortcut:not([iridium-enabled]) { 177 | opacity: 0.5; 178 | } 179 | #iridium-video-focus:not([iridium-enabled]) #iridium-on, 180 | #iridium-video-focus[iridium-enabled] #iridium-off { 181 | display: none; 182 | } 183 | #iridium-monetization:not(.monetized) .iridium-on, 184 | #iridium-monetization.monetized .iridium-off { 185 | display: none; 186 | } 187 | html[dark] #iridium-player-tools .monetized { 188 | fill: #3fd20a; 189 | } 190 | #iridium-player-tools .monetized { 191 | fill: #3ad406; 192 | } 193 | html[dark] #iridium-player-tools .sponsored { 194 | fill: #3e8bff; 195 | } 196 | #iridium-player-tools .sponsored { 197 | fill: #0677d4; 198 | } 199 | #iridium-monetization-count { 200 | font-size: 10px; 201 | position: absolute; 202 | color: var(--yt-spec-text-primary); 203 | bottom: 0; 204 | right: 0; 205 | background: var(--yt-spec-base-background); 206 | border-radius: 12px; 207 | padding: 0 3px; 208 | } 209 | #iridium-monetization-count { 210 | font-size: 10px; 211 | position: absolute; 212 | color: var(--yt-spec-text-primary); 213 | bottom: 0; 214 | right: 0; 215 | background: var(--yt-spec-base-background); 216 | border-radius: 12px; 217 | padding: 0 3px; 218 | } 219 | #iridium-player-tools > div:hover #iridium-monetization-count { 220 | display: none; 221 | } 222 | /* end | player tools */ 223 | 224 | /* ini | always visible */ 225 | html[always-visible-player] .ytp-miniplayer-button, 226 | html[always-visible-player] .ytp-size-button { 227 | display: none !important; 228 | } 229 | html[always-visible-player]:not(:has(ytd-watch-flexy[fullscreen])) #movie_player { 230 | position: fixed; 231 | z-index: 9999; 232 | height: 225px; 233 | width: 400px; 234 | bottom: 10px; 235 | right: 10px; 236 | box-shadow: 0 4px 5px 0 rgba(0, 0, 0, .14), 0 1px 10px 0 rgba(0, 0, 0, .12), 0 2px 4px -1px rgba(0, 0, 0, .4); 237 | } 238 | html[always-visible-player] #movie_player::before { 239 | background-color: #000; 240 | bottom: 0; 241 | content: ""; 242 | display: block; 243 | left: 0; 244 | position: absolute; 245 | right: 0; 246 | top: 0; 247 | } 248 | html[always-visible-player][moving] #movie_player { 249 | opacity: 0.9; 250 | } 251 | html[always-visible-player][moving] #movie_player::after { 252 | background-color: #fff; 253 | bottom: 0; 254 | content: ""; 255 | display: block; 256 | left: 0; 257 | opacity: .4; 258 | position: absolute; 259 | right: 0; 260 | top: 0; 261 | z-index: 99; 262 | } 263 | html[dark][always-visible-player][moving] #movie_player::after { 264 | background-color: #000; 265 | } 266 | /* end | always visible */ 267 | 268 | /* ini | ambient mode disabled */ 269 | html[ambient-mode-disabled] #cinematics-container { 270 | display: none; 271 | } 272 | /* end | ambient mode disabled */ -------------------------------------------------------------------------------- /src/chrome/css/options.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: "Roboto"; 3 | font-weight: 400; 4 | src: url("../font/Roboto-Regular.ttf"); 5 | } 6 | 7 | @font-face { 8 | font-family: "Roboto"; 9 | font-weight: 500; 10 | src: url("../font/Roboto-Medium.ttf"); 11 | } 12 | 13 | @font-face { 14 | font-family: "Roboto"; 15 | font-weight: 600; 16 | src: url("../font/Roboto-Bold.ttf"); 17 | } 18 | 19 | @keyframes breatheStartEffect { 20 | 0% { 21 | stop-color: #0ff; 22 | } 23 | 50% { 24 | stop-color: var(--logo-color); 25 | } 26 | 100% { 27 | stop-color: #0ff; 28 | } 29 | } 30 | 31 | @keyframes breatheStopEffect { 32 | 0% { 33 | stop-color: #f0f; 34 | } 35 | 50% { 36 | stop-color: var(--logo-color); 37 | } 38 | 100% { 39 | stop-color: #f0f; 40 | } 41 | } 42 | 43 | @keyframes shimmer { 44 | 100% { 45 | mask-position: left 46 | } 47 | } 48 | 49 | html { 50 | --sidebar-width: 240px; 51 | --logo-height: 20px; 52 | --logo-color: #212121; 53 | --link-color: #065fd4; 54 | --background-color: #fff; 55 | --text-color: #0f0f0f; 56 | --text-primary-color: #0f0f0f; 57 | --text-secondary-color: #606060; 58 | --divider-border-color: #0000001a; 59 | --pre-background-color: #00000024; 60 | --item-hover-background-color: #0000000d; 61 | --item-selected-background-color: #0000001a; 62 | --toggle-switch-button-color: #030303; 63 | --toggle-switch-button-active-color: #065fd4; 64 | --toggle-switch-slider-color: #909090; 65 | --dropdown-background-color: #e5e5e5; 66 | --button-background-color: var(--background-color); 67 | --button-background-color-hover: #def1ff; 68 | --button-text-color: var(--toggle-switch-button-active-color); 69 | } 70 | 71 | html[dark] { 72 | --logo-color: #fff; 73 | --link-color: #3ea6ff; 74 | --background-color: #0f0f0f; 75 | --text-color: #f1f1f1; 76 | --text-primary-color: #fff; 77 | --text-secondary-color: #aaa; 78 | --divider-border-color: #fff3; 79 | --pre-background-color: #ffffff24; 80 | --item-hover-background-color: #ffffff1a; 81 | --item-selected-background-color: #fff3; 82 | --toggle-switch-button-color: #fff; 83 | --toggle-switch-button-active-color: #3ea6ff; 84 | --toggle-switch-slider-color: #717171; 85 | --dropdown-background-color: #3f3f3f; 86 | --button-background-color: var(--background-color); 87 | --button-background-color-hover: #263850; 88 | --button-text-color: var(--toggle-switch-button-active-color); 89 | } 90 | 91 | body { 92 | font-family: "Roboto", "Arial", sans-serif; 93 | margin: 0 auto; 94 | position: relative; 95 | background-color: var(--background-color); 96 | height: 100%; 97 | width: 100%; 98 | color: var(--text-color); 99 | } 100 | 101 | a, 102 | .faux-link { 103 | display: inline; 104 | color: var(--link-color) !important; 105 | text-decoration: none; 106 | cursor: pointer; 107 | } 108 | 109 | :focus { 110 | outline: none; 111 | } 112 | 113 | ::-moz-focus-inner { 114 | border: 0; 115 | } 116 | 117 | [hidden] { 118 | display: none; 119 | } 120 | 121 | pre { 122 | display: inline; 123 | background: var(--pre-background-color); 124 | padding: 2px 6px; 125 | border-radius: 4px; 126 | } 127 | 128 | #version { 129 | position: fixed; 130 | bottom: 0; 131 | right: 0; 132 | opacity: 0.5; 133 | font-size: 12px; 134 | padding: 6px 12px; 135 | user-select: none; 136 | pointer-events: none; 137 | } 138 | 139 | .shimmer { 140 | mask: linear-gradient(-60deg, #000 30%, #0005, #000 70%) right/400% 100%; 141 | background-repeat: no-repeat; 142 | animation: shimmer 2.5s infinite; 143 | width: fit-content; 144 | } 145 | 146 | .borderBottom { 147 | border-bottom: 1px solid var(--divider-border-color); 148 | } 149 | 150 | #title { 151 | width: var(--sidebar-width); 152 | font-size: 0; 153 | text-align: center; 154 | } 155 | 156 | #logo { 157 | height: var(--logo-height); 158 | padding: 0 16px; 159 | margin: 18px 12px; 160 | } 161 | 162 | #logo .name path { 163 | fill: var(--logo-color); 164 | } 165 | 166 | .logo-start-gradient { 167 | animation: breatheStartEffect 5s linear infinite; 168 | } 169 | 170 | .logo-stop-gradient { 171 | animation: breatheStopEffect 5s linear infinite; 172 | } 173 | 174 | #container { 175 | display: flex; 176 | } 177 | 178 | #menu { 179 | width: var(--sidebar-width); 180 | min-width: var(--sidebar-width); 181 | padding: 18px 0; 182 | } 183 | 184 | .item { 185 | height: 40px; 186 | margin: 0 12px; 187 | border-radius: 10px; 188 | cursor: pointer; 189 | user-select: none; 190 | padding: 0 16px; 191 | text-overflow: ellipsis; 192 | display: block; 193 | overflow: hidden; 194 | white-space: nowrap; 195 | font-size: 14px; 196 | line-height: 40px; 197 | font-weight: 400; 198 | } 199 | 200 | .item:hover { 201 | background-color: var(--item-hover-background-color); 202 | } 203 | 204 | .item[data-active] { 205 | background-color: var(--item-selected-background-color); 206 | font-weight: 500; 207 | } 208 | 209 | #contents { 210 | padding: 18px 32px; 211 | max-width: 1000px; 212 | flex-grow: 1; 213 | margin: 0 auto; 214 | } 215 | 216 | .content:not([data-active]) { 217 | display: none; 218 | } 219 | 220 | .contentTitle { 221 | line-height: 40px; 222 | font-size: 20px; 223 | font-weight: 500; 224 | } 225 | 226 | .contentDescription { 227 | color: var(--text-secondary-color); 228 | font-size: 12px; 229 | padding-bottom: 24px; 230 | margin-bottom: 24px; 231 | } 232 | 233 | .settingGroup { 234 | display: flex; 235 | } 236 | 237 | .settingLabel { 238 | color: var(--text-color); 239 | font-size: 14px; 240 | font-weight: 500; 241 | width: 160px; 242 | min-width: 160px; 243 | margin-right: 56px; 244 | } 245 | 246 | .setting { 247 | width: 100%; 248 | display: flex; 249 | margin-bottom: 24px; 250 | transition: opacity .08s; 251 | cursor: default; 252 | } 253 | 254 | .setting.disabled { 255 | opacity: 0.4; 256 | user-select: none; 257 | pointer-events: none; 258 | } 259 | 260 | .setting select { 261 | font-family: "Roboto", "Arial", sans-serif; 262 | font-size: 14px; 263 | font-weight: 500; 264 | padding: 8px 16px; 265 | background-color: var(--dropdown-background-color); 266 | color: var(--text-primary-color); 267 | border-radius: 6px; 268 | border: 0 none; 269 | margin-bottom: 6px; 270 | min-width: 120px; 271 | } 272 | 273 | .settingDescription { 274 | } 275 | 276 | .settingDescription.highlight { 277 | color: var(--text-primary-color); 278 | font-size: 14px; 279 | font-weight: 500; 280 | margin-bottom: 4px; 281 | } 282 | 283 | .settingDescription:not(.highlight) { 284 | color: var(--text-secondary-color); 285 | font-size: 14px; 286 | font-weight: 400; 287 | } 288 | 289 | .switch { 290 | position: relative; 291 | display: flex; 292 | width: 38px; 293 | height: 20px; 294 | min-width: 38px; 295 | padding-right: 20px; 296 | } 297 | 298 | .switch input { 299 | opacity: 0; 300 | width: 0; 301 | height: 0; 302 | pointer-events: none; 303 | } 304 | 305 | .slider { 306 | position: absolute; 307 | top: 0; 308 | left: 0; 309 | right: 0; 310 | bottom: 0; 311 | pointer-events: none; 312 | } 313 | 314 | .slider::before { 315 | position: absolute; 316 | content: ""; 317 | background-color: var(--toggle-switch-slider-color); 318 | opacity: 0.4; 319 | height: 14px; 320 | width: 36px; 321 | transition: .08s; 322 | margin: 3px 1px; 323 | border-radius: 8px; 324 | } 325 | 326 | .slider::after { 327 | position: absolute; 328 | box-shadow: 0 1px 5px 0 rgba(0, 0, 0, 0.6); 329 | content: ""; 330 | height: 20px; 331 | width: 20px; 332 | background-color: var(--toggle-switch-button-color); 333 | transition: .08s; 334 | top: 0; 335 | left: 0; 336 | border-radius: 50%; 337 | } 338 | 339 | input:checked + .slider::after { 340 | background-color: var(--toggle-switch-button-active-color); 341 | left: 18px; 342 | } 343 | 344 | .radioGroup { 345 | margin: 0 0 24px; 346 | padding: 0; 347 | border: none; 348 | color: var(--text-secondary-color); 349 | } 350 | 351 | .radio { 352 | --radio-width: 20px; 353 | font-size: 16px; 354 | position: relative; 355 | display: flex; 356 | height: 20px; 357 | min-width: var(--radio-width); 358 | min-height: 20px; 359 | padding-left: calc(var(--radio-width) + 16px); 360 | margin-bottom: 20px; 361 | } 362 | 363 | .radio input { 364 | opacity: 0; 365 | width: 0; 366 | height: 0; 367 | pointer-events: none; 368 | display: none; 369 | } 370 | 371 | .radio .button::before { 372 | position: absolute; 373 | content: ""; 374 | border: 2px solid var(--toggle-switch-button-color); 375 | height: 20px; 376 | width: 20px; 377 | left: 0; 378 | transition: .08s; 379 | box-sizing: border-box; 380 | border-radius: 50%; 381 | } 382 | 383 | .radio .button::after { 384 | position: absolute; 385 | content: ""; 386 | background-color: var(--toggle-switch-button-color); 387 | height: 10px; 388 | width: 10px; 389 | left: 5px; 390 | top: 0; 391 | bottom: 0; 392 | margin: auto; 393 | transition: .08s; 394 | box-sizing: border-box; 395 | border-radius: 50%; 396 | transform: scale(0); 397 | } 398 | 399 | input:checked + .button::before { 400 | border-color: var(--toggle-switch-button-active-color); 401 | } 402 | 403 | input:checked + .button::after { 404 | background-color: var(--toggle-switch-button-active-color); 405 | transform: scale(1); 406 | } 407 | 408 | #blacklistControls { 409 | display: flex; 410 | margin-bottom: 12px; 411 | gap: 16px; 412 | align-items: center; 413 | font-size: 14px; 414 | font-weight: 500; 415 | justify-content: space-between; 416 | } 417 | 418 | #filterChannelsContainer { 419 | position: relative; 420 | line-height: 46px; 421 | padding: 0 16px; 422 | } 423 | 424 | #filterChannelsContainer::before { 425 | position: absolute; 426 | content: ""; 427 | top: 0; 428 | bottom: 0; 429 | left: 0; 430 | right: 0; 431 | border-radius: 12px; 432 | border: 1px solid var(--divider-border-color); 433 | } 434 | 435 | #filterChannels { 436 | font-family: "Roboto", "Arial", sans-serif; 437 | position: relative; 438 | background: var(--background-color); 439 | color: var(--text-color); 440 | border: none; 441 | font-size: 14px; 442 | font-weight: 500; 443 | } 444 | 445 | #blacklistChannels { 446 | padding: 8px; 447 | position: relative; 448 | display: flex; 449 | flex-wrap: wrap; 450 | gap: 8px; 451 | line-height: 36px; 452 | } 453 | 454 | #blacklistChannels::before { 455 | position: absolute; 456 | content: ""; 457 | border-radius: 10px; 458 | background: var(--toggle-switch-slider-color); 459 | opacity: 0.1; 460 | top: 0; 461 | bottom: 0; 462 | left: 0; 463 | right: 0; 464 | z-index: -1; 465 | } 466 | 467 | #blacklistActions { 468 | display: flex; 469 | gap: 16px; 470 | align-items: center; 471 | } 472 | 473 | .action-button { 474 | background-color: var(--button-background-color); 475 | color: var(--button-text-color); 476 | font-size: 14px; 477 | font-weight: 500; 478 | border-radius: 100px; 479 | text-align: center; 480 | padding: 10px 16px; 481 | cursor: pointer; 482 | user-select: none; 483 | border: 1px solid var(--divider-border-color); 484 | text-transform: uppercase; 485 | } 486 | 487 | .action-button:not(.disabled):hover { 488 | background-color: var(--button-background-color-hover); 489 | border-color: transparent; 490 | } 491 | 492 | .action-button.disabled { 493 | pointer-events: none; 494 | filter: grayscale(1); 495 | } 496 | 497 | .channel { 498 | position: relative; 499 | display: flex; 500 | align-items: center; 501 | width: fit-content; 502 | padding: 0 16px; 503 | background: var(--item-selected-background-color); 504 | border-radius: 10px; 505 | font-weight: 500; 506 | cursor: pointer; 507 | line-height: 36px; 508 | min-width: 60px; 509 | justify-content: center; 510 | } 511 | 512 | .remove { 513 | position: absolute; 514 | left: 0; 515 | right: 0; 516 | margin: 0 auto; 517 | fill: var(--text-color); 518 | transition: 0.2s; 519 | user-select: none; 520 | pointer-events: none; 521 | } 522 | 523 | .channel:not(:hover) .remove { 524 | opacity: 0; 525 | } 526 | 527 | .channelName { 528 | transition: 0.2s; 529 | user-select: none; 530 | pointer-events: none; 531 | } 532 | 533 | .channel:hover .channelName { 534 | opacity: 0.2; 535 | } 536 | 537 | #backdrop { 538 | position: fixed; 539 | top: 0; 540 | bottom: 0; 541 | left: 0; 542 | right: 0; 543 | display: flex; 544 | align-items: center; 545 | justify-content: center; 546 | } 547 | 548 | #backdrop::before { 549 | position: absolute; 550 | content: ""; 551 | background-color: var(--button-background-color); 552 | opacity: 0.9; 553 | top: 0; 554 | bottom: 0; 555 | left: 0; 556 | right: 0; 557 | z-index: -1; 558 | } 559 | 560 | #dialog { 561 | background-color: var(--background-color); 562 | min-width: 400px; 563 | padding: 24px; 564 | border-radius: 20px; 565 | box-shadow: 0 5px 20px black; 566 | display: flex; 567 | flex-direction: column; 568 | gap: 16px; 569 | } 570 | 571 | #dialog input { 572 | font-family: "Roboto", "Arial", sans-serif; 573 | background-color: var(--background-color); 574 | font-size: 16px; 575 | border-radius: 8px; 576 | line-height: 26px; 577 | padding: 4px 8px; 578 | flex: 1; 579 | color: var(--text-color); 580 | border: 1px solid var(--divider-border-color); 581 | } 582 | 583 | #searchForm { 584 | display: flex; 585 | gap: 16px; 586 | color: var(--text-secondary-color); 587 | } 588 | 589 | #searchResult { 590 | position: relative; 591 | display: flex; 592 | align-items: center; 593 | padding: 16px; 594 | flex-flow: column; 595 | gap: 8px; 596 | } 597 | 598 | #searchResult::before { 599 | position: absolute; 600 | content: ""; 601 | background: var(--toggle-switch-slider-color); 602 | opacity: 0.1; 603 | top: 0; 604 | bottom: 0; 605 | left: 0; 606 | right: 0; 607 | border-radius: 10px; 608 | user-select: none; 609 | pointer-events: none; 610 | } 611 | 612 | #searchResult > div { 613 | z-index: 0; 614 | } 615 | 616 | #searchChannelAvatarContainer { 617 | border-radius: 100%; 618 | width: 64px; 619 | height: 64px; 620 | overflow: hidden; 621 | } 622 | 623 | #searchChannelName { 624 | border-radius: 4px; 625 | font-weight: 500; 626 | } 627 | 628 | #searchResultMessage { 629 | position: absolute; 630 | opacity: 1; 631 | top: 0; 632 | bottom: 0; 633 | margin: 0 auto; 634 | display: flex; 635 | align-items: center; 636 | } 637 | 638 | #searchChannelAvatar { 639 | height: 100%; 640 | width: 100%; 641 | } 642 | 643 | #dialog:not(.noResults) #searchResultMessage { 644 | display: none; 645 | } 646 | 647 | #dialog.noResults #searchChannelAvatarContainer, 648 | #dialog.noResults #searchChannelName { 649 | opacity: 0; 650 | user-select: none; 651 | pointer-events: none; 652 | } 653 | 654 | #blockedIndicator { 655 | color: var(--background-color); 656 | font-size: 10px; 657 | font-weight: 500; 658 | margin-top: -20px; 659 | background: var(--link-color); 660 | padding: 2px 4px; 661 | border-radius: 4px; 662 | user-select: none; 663 | pointer-events: none; 664 | } 665 | 666 | #dialog:not(.channelBlocked) #blockedIndicator { 667 | opacity: 0; 668 | } 669 | 670 | #dialogAction { 671 | display: flex; 672 | gap: 16px; 673 | justify-content: center; 674 | } 675 | 676 | #dialog:not(.noResults) #addDialog:hover, 677 | #dialog:not(.channelBlocked) #addDialog:hover { 678 | background-color: var(--button-background-color-hover); 679 | border-color: transparent; 680 | } 681 | 682 | #dialog.noResults #addDialog, 683 | #dialog.channelBlocked #addDialog { 684 | pointer-events: none; 685 | filter: grayscale(1); 686 | } -------------------------------------------------------------------------------- /src/chrome/font/LICENSE.txt: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /src/chrome/font/Roboto-Black.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ParticleCore/Iridium/be0acb55146aac60c34eef3fe22f3dda407aa2fa/src/chrome/font/Roboto-Black.ttf -------------------------------------------------------------------------------- /src/chrome/font/Roboto-BlackItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ParticleCore/Iridium/be0acb55146aac60c34eef3fe22f3dda407aa2fa/src/chrome/font/Roboto-BlackItalic.ttf -------------------------------------------------------------------------------- /src/chrome/font/Roboto-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ParticleCore/Iridium/be0acb55146aac60c34eef3fe22f3dda407aa2fa/src/chrome/font/Roboto-Bold.ttf -------------------------------------------------------------------------------- /src/chrome/font/Roboto-BoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ParticleCore/Iridium/be0acb55146aac60c34eef3fe22f3dda407aa2fa/src/chrome/font/Roboto-BoldItalic.ttf -------------------------------------------------------------------------------- /src/chrome/font/Roboto-Italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ParticleCore/Iridium/be0acb55146aac60c34eef3fe22f3dda407aa2fa/src/chrome/font/Roboto-Italic.ttf -------------------------------------------------------------------------------- /src/chrome/font/Roboto-Light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ParticleCore/Iridium/be0acb55146aac60c34eef3fe22f3dda407aa2fa/src/chrome/font/Roboto-Light.ttf -------------------------------------------------------------------------------- /src/chrome/font/Roboto-LightItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ParticleCore/Iridium/be0acb55146aac60c34eef3fe22f3dda407aa2fa/src/chrome/font/Roboto-LightItalic.ttf -------------------------------------------------------------------------------- /src/chrome/font/Roboto-Medium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ParticleCore/Iridium/be0acb55146aac60c34eef3fe22f3dda407aa2fa/src/chrome/font/Roboto-Medium.ttf -------------------------------------------------------------------------------- /src/chrome/font/Roboto-MediumItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ParticleCore/Iridium/be0acb55146aac60c34eef3fe22f3dda407aa2fa/src/chrome/font/Roboto-MediumItalic.ttf -------------------------------------------------------------------------------- /src/chrome/font/Roboto-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ParticleCore/Iridium/be0acb55146aac60c34eef3fe22f3dda407aa2fa/src/chrome/font/Roboto-Regular.ttf -------------------------------------------------------------------------------- /src/chrome/font/Roboto-Thin.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ParticleCore/Iridium/be0acb55146aac60c34eef3fe22f3dda407aa2fa/src/chrome/font/Roboto-Thin.ttf -------------------------------------------------------------------------------- /src/chrome/font/Roboto-ThinItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ParticleCore/Iridium/be0acb55146aac60c34eef3fe22f3dda407aa2fa/src/chrome/font/Roboto-ThinItalic.ttf -------------------------------------------------------------------------------- /src/chrome/html/options.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Iridium 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 36 |
37 |
38 | 48 |
49 |
50 |
General
51 |
Various settings that control the extension and website
52 |
53 |
Extension settings
54 |
55 |
56 | 60 |
61 |
Display extension button on YouTube
62 |
Show an extension shortcut button on YouTube pages
63 |
64 |
65 |
66 | 70 |
71 |
Sync extension settings
72 |
Extension settings will be synced across browsers with the same user profile logged in
73 |
74 |
75 |
76 |
77 |
78 |
Manage settings
79 |
80 |
81 |
82 | 83 |
Extension settings are exported in a json file format
84 |
85 |
86 |
87 |
88 | 89 |
Restore settings from an existing backup json file format
90 |
91 |
92 |
93 |
94 | 95 |
Resetting the extension settings may help resolve certain issues, but remember to back up the current settings first
96 |
97 |
98 |
99 |
100 |
Donate
101 |
Contribute to help keep the extension alive
102 |
103 |
Donation options
104 |
105 |
106 |
107 | 108 |
You may donate one time only or set up a monthly donation
109 |
110 |
111 |
112 |
113 | 114 |
Join my patreon and follow up with less technical summarized updates
115 |
116 |
117 |
118 |
119 |
120 |
121 |
Ad manager
122 |
Manage how ads are displayed in video and other web pages
123 |
124 |
General
125 |
126 |
127 | 131 |
132 |
Opt out of all ads
133 |
No ads will be displayed on the website, but other settings may take precedence
134 |
135 |
136 |
137 |
138 |
139 |
Home page
140 |
141 |
142 | 146 |
147 |
Masthead ad
148 |
Allow a large banner ad to show on the top of the page
149 |
150 |
151 |
152 | 156 |
157 |
In-feed ads
158 |
Allow ads to show in the home page video list
159 |
160 |
161 |
162 |
163 |
164 |
Search page
165 |
166 |
167 | 171 |
172 |
In-feed ads
173 |
Allow ads to show in the search page results
174 |
175 |
176 |
177 |
178 |
179 |
Video page
180 |
181 |
182 | 186 |
187 |
Subscribed ads
188 |
Only show ads on videos from subscribed channels
189 |
190 |
191 |
192 | 196 |
197 |
In-feed ads
198 |
Allow ads to be displayed in the suggested videos sidebar
199 |
200 |
201 |
202 | 206 |
207 |
Video ads
208 |
Allow ads to be displayed in the video
209 |
210 |
211 |
212 | 216 |
217 |
Tagged product ads
218 |
Allow small banners of tagged affiliate products in the video
219 |
220 |
221 |
222 |
223 |
224 |
225 |
Website
226 |
Personalize the aspect and behavior of YouTube
227 |
228 |
Visual
229 |
230 |
231 | 235 |
236 |
Show full titles in thumbnails
237 |
Makes the titles in the thumbnails display in full
238 |
239 |
240 |
241 |
242 |
243 |
Theme
244 |
245 |
246 |
247 | 252 | 257 | 262 |
263 |
Enforces the selected theme on YouTube and in the extension options page. Device theme will default to Dark theme when not available
264 |
265 |
266 |
267 |
268 |
269 |
270 |
Logo redirect
271 |
272 |
273 | 277 |
278 |
Redirect to subscriptions page
279 |
Clicking on the YouTube logo will redirect to the subscriptions page instead of the homepage
280 |
281 |
282 |
283 |
284 |
285 |
Channel
286 |
287 |
288 | 292 |
293 |
Autoplay channel trailer
294 |
Channel trailers will play automatically. Does not override the browser settings
295 |
296 |
297 |
298 |
299 |
300 |
Channel tab
301 |
302 |
303 |
304 | 317 |
Clicking on a channel link will automatically open the specified tab
318 |
319 |
320 |
321 |
322 |
323 |
Shorts
324 |
325 |
326 | 330 |
331 |
Home page
332 |
Short videos will show on the home page
333 |
334 |
335 |
336 | 340 |
341 |
Subscriptions
342 |
Short videos will show in the subscriptions
343 |
344 |
345 |
346 | 350 |
351 |
Video Page
352 |
Short videos will show in video page sidebar
353 |
354 |
355 |
356 | 360 |
361 |
Search results
362 |
Short videos will show in search results
363 |
364 |
365 |
366 |
367 |
368 |
369 |
Video page
370 |
Customize the video page and player
371 |
372 |
Page
373 |
374 |
375 | 379 |
380 |
Video focus
381 |
Fade out the webpage while the video is playing
382 |
383 |
384 |
385 | 389 |
390 |
Creator merch
391 |
Allows the creator merch to be shown below the video details
392 |
393 |
394 |
395 | 399 |
400 |
Linked video count
401 |
Creates a link that shows the number of videos uploaded by the channel next to the subscriber count
402 |
403 |
404 |
405 | 409 |
410 |
Ambient Mode
411 |
Allows the lighting effect around the video player to be displayed if it is enabled in the player settings
412 |
413 |
414 |
415 |
416 |
417 |
Playlist
418 |
419 |
420 | 424 |
425 |
Reverse playlist control
426 |
Show a button on playlists to reverse the playlist order
427 |
428 |
429 |
430 |
431 |
432 |
Video quality
433 |
434 |
435 |
436 | 451 |
Enforces the preferred or closest quality option
452 |
453 |
454 |
455 |
456 |
457 |
Playback speed
458 |
459 |
460 |
461 | 474 |
Enforces the preferred or closest playback speed option
475 |
476 |
477 |
478 |
479 |
480 |
Player
481 |
482 |
483 | 487 |
488 |
Super theater
489 |
Switching to theater mode will make the player cover the full browser while allowing the page to be scrolled
490 |
491 |
492 |
493 | 497 |
498 |
Show super theater scrollbar
499 |
Controls the vertical scrollbar visibility while in super theater mode
500 |
501 |
502 |
503 | 507 |
508 |
Always visible
509 |
Changes into an always visible mini player when less than half of the video is visible. The mini player can be moved using the right mouse button
510 |
511 |
512 |
513 | 517 |
518 |
HFR allowed
519 |
Allows HFR (High Frame Rate) streams to be played. YouTube no longer provides normal framerate options above 720p when the respective HFR exists
520 |
521 |
522 |
523 | 527 |
528 |
Autoplay
529 |
Videos will play automatically. Does not override the browser settings
530 |
531 |
532 |
533 | 537 |
538 |
Loudness normalization
539 |
Enables YouTube's audio loudness normalization
540 |
541 |
542 |
543 | 547 |
548 |
Info cards
549 |
Allows info cards to show on the video
550 |
551 |
552 |
553 | 557 |
558 |
Annotations
559 |
Allow annotations to show on the video
560 |
561 |
562 |
563 | 567 |
568 |
End screen hidden
569 |
Hide end screen when the cursor is over the video
570 |
571 |
572 |
573 |
574 |
575 |
Volume
576 |
577 |
578 | 582 |
583 |
Scroll volume
584 |
Change video volume by scrolling on the video player, or by holding shift and scrolling anywhere in the page if the option below is enabled
585 |
586 |
587 |
588 | 592 |
593 |
Shift + scroll volume
594 |
Changing volume using the scroll wheel requires the shift key to be pressed, and can be done from anywhere in the page
595 |
596 |
597 |
598 |
599 |
600 |
Volume step
601 |
602 |
603 |
604 | 618 |
Number of volume steps each scroll will change at once
619 |
620 |
621 |
622 |
623 |
Utils and shortcuts
624 |
Show utils and shortcuts below the player. Shortcuts allow features to be controlled directly
625 |
626 |
Utils
627 |
628 |
629 | 633 |
634 |
Video screenshot
635 |
Allows a screenshot to be taken of a playing video at the current native resolution
636 |
637 |
638 |
639 | 643 |
644 |
Video thumbnail
645 |
Opens the highest quality thumbnail available
646 |
647 |
648 |
649 | 653 |
654 |
Monetization info
655 |
Shows if a video is monetized and how many ads are configured
656 |
657 |
658 |
659 |
660 |
661 |
Shortcuts
662 |
663 |
664 | 668 |
669 |
Autoplay shortcut
670 |
Shortcut that allows autoplay to be controlled from the video page
671 |
672 |
673 |
674 | 678 |
679 |
Video focus shortcut
680 |
Shortcut that allows video focus to be controlled from the video page
681 |
682 |
683 |
684 |
685 |
686 |
687 |
Blacklist
688 |
Videos from blocked channels will no longer be displayed
689 |
690 |
Blacklist
691 |
692 |
693 | 697 |
698 |
Blacklist enabled
699 |
Videos from channels in the blacklist will not be displayed except in its own channel page
700 |
701 |
702 |
703 | 707 |
708 |
Blacklist button
709 |
Displays a button in the three vertical dots context menu of video thumbnails to add that channel to the blacklist. This option is not available on vertical shorts thumbnails
710 |
711 |
712 |
713 |
714 |
Blacklisted channels
715 |
Remove blacklisted channels, add channels manually, import from an existing backup, or export the current list
716 |
717 |
718 | 719 |
720 |
721 |
Add
722 |
Import
723 |
Export
724 |
725 |
726 |
727 |
728 |
729 |
Help
730 |
Troubleshoot or report problems with the extension
731 |
732 |
733 |
734 |
735 |
Report a problem
736 |
If you found an issue or a bug with the extension please follow the instructions for reporting a bug below
737 | 738 |
739 |
740 |
741 |
742 |
743 |
744 |
745 |
746 | 747 | 748 | -------------------------------------------------------------------------------- /src/chrome/icons/128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ParticleCore/Iridium/be0acb55146aac60c34eef3fe22f3dda407aa2fa/src/chrome/icons/128.png -------------------------------------------------------------------------------- /src/chrome/icons/144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ParticleCore/Iridium/be0acb55146aac60c34eef3fe22f3dda407aa2fa/src/chrome/icons/144.png -------------------------------------------------------------------------------- /src/chrome/icons/16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ParticleCore/Iridium/be0acb55146aac60c34eef3fe22f3dda407aa2fa/src/chrome/icons/16.png -------------------------------------------------------------------------------- /src/chrome/icons/32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ParticleCore/Iridium/be0acb55146aac60c34eef3fe22f3dda407aa2fa/src/chrome/icons/32.png -------------------------------------------------------------------------------- /src/chrome/icons/48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ParticleCore/Iridium/be0acb55146aac60c34eef3fe22f3dda407aa2fa/src/chrome/icons/48.png -------------------------------------------------------------------------------- /src/chrome/icons/64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ParticleCore/Iridium/be0acb55146aac60c34eef3fe22f3dda407aa2fa/src/chrome/icons/64.png -------------------------------------------------------------------------------- /src/chrome/icons/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ParticleCore/Iridium/be0acb55146aac60c34eef3fe22f3dda407aa2fa/src/chrome/icons/favicon.ico -------------------------------------------------------------------------------- /src/chrome/img/iridium.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /src/chrome/js/background.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | globalThis.browser ??= chrome; 4 | 5 | const openOptions = () => { 6 | browser.runtime.openOptionsPage()?.then?.(); 7 | } 8 | const Api = { 9 | debounce: false, 10 | onMessageListener: (data) => { 11 | 12 | if (!data.type || !data.payload || Api.debounce) { 13 | return; 14 | } 15 | 16 | // prevents the options page from opening in duplicate 17 | Api.debounce = true; 18 | setTimeout(() => Api.debounce = false, 1000); 19 | 20 | if (data.payload === SettingData.extensionButton.id) { 21 | openOptions(); 22 | } 23 | 24 | } 25 | } 26 | const onConnect = (port) => { 27 | port.onMessage.addListener(Api.onMessageListener); 28 | } 29 | 30 | browser.runtime.onConnect.addListener(onConnect); 31 | // chrome mv3 32 | browser.action.onClicked.addListener(openOptions); -------------------------------------------------------------------------------- /src/chrome/js/chrome-wrapper.js: -------------------------------------------------------------------------------- 1 | (() => { 2 | 3 | if (Object.hasOwn(window, "mainScript") && mainScript === undefined) { 4 | return; 5 | } 6 | 7 | const extensionId = "fdhajofnodmginhfnknimmpdhcgkcldj"; 8 | const SettingData = { 9 | extensionButton: { 10 | id: "extensionButton", 11 | default: true, 12 | }, 13 | syncSettings: { 14 | id: "syncSettings", 15 | default: false, 16 | }, 17 | fullTitles: { 18 | id: "fullTitles", 19 | default: true, 20 | }, 21 | theme: { 22 | id: "theme", 23 | default: "deviceTheme", 24 | }, 25 | logoSubscriptions: { 26 | id: "logoSubscriptions", 27 | default: false, 28 | }, 29 | autoplayChannelTrailer: { 30 | id: "autoplayChannelTrailer", 31 | default: false, 32 | }, 33 | channelTab: { 34 | id: "channelTab", 35 | default: "featured", 36 | }, 37 | homeShorts: { 38 | id: "homeShorts", 39 | default: true, 40 | }, 41 | subscriptionsShorts: { 42 | id: "subscriptionsShorts", 43 | default: true, 44 | }, 45 | videoPageShorts: { 46 | id: "videoPageShorts", 47 | default: true, 48 | }, 49 | searchShorts: { 50 | id: "searchShorts", 51 | default: true, 52 | }, 53 | adOptOutAll: { 54 | id: "adOptOutAll", 55 | default: false, 56 | }, 57 | adSubscribed: { 58 | id: "adSubscribed", 59 | default: false, 60 | }, 61 | adVideoFeed: { 62 | id: "adVideoFeed", 63 | default: false, 64 | }, 65 | adInVideo: { 66 | id: "adInVideo", 67 | default: false, 68 | }, 69 | adTaggedProducts: { 70 | id: "adTaggedProducts", 71 | default: false, 72 | }, 73 | adMasthead: { 74 | id: "adMasthead", 75 | default: false, 76 | }, 77 | adHomeFeed: { 78 | id: "adHomeFeed", 79 | default: false, 80 | }, 81 | adSearchFeed: { 82 | id: "adSearchFeed", 83 | default: false, 84 | }, 85 | videoFocus: { 86 | id: "videoFocus", 87 | default: true, 88 | }, 89 | creatorMerch: { 90 | id: "creatorMerch", 91 | default: true, 92 | }, 93 | videoCount: { 94 | id: "videoCount", 95 | default: true, 96 | }, 97 | ambientMode: { 98 | id: "ambientMode", 99 | default: true, 100 | }, 101 | reversePlaylist: { 102 | id: "reversePlaylist", 103 | default: true, 104 | }, 105 | reversePlaylistToggled: { 106 | id: "reversePlaylistToggled", 107 | default: false, 108 | }, 109 | superTheater: { 110 | id: "superTheater", 111 | default: true, 112 | }, 113 | superTheaterScrollbar: { 114 | id: "superTheaterScrollbar", 115 | default: true, 116 | }, 117 | defaultQuality: { 118 | id: "defaultQuality", 119 | default: "auto", 120 | }, 121 | defaultSpeed: { 122 | id: "defaultSpeed", 123 | default: "-1", 124 | }, 125 | alwaysVisible: { 126 | id: "alwaysVisible", 127 | default: true, 128 | }, 129 | alwaysVisiblePosition: { 130 | id: "alwaysVisiblePosition", 131 | default: {}, 132 | }, 133 | hfrAllowed: { 134 | id: "hfrAllowed", 135 | default: true, 136 | }, 137 | autoplay: { 138 | id: "autoplay", 139 | default: false, 140 | }, 141 | loudness: { 142 | id: "loudness", 143 | default: false, 144 | }, 145 | scrollVolume: { 146 | id: "scrollVolume", 147 | default: true, 148 | }, 149 | scrollVolumeShift: { 150 | id: "scrollVolumeShift", 151 | default: true, 152 | }, 153 | scrollVolumeStep: { 154 | id: "scrollVolumeStep", 155 | default: 5, 156 | }, 157 | infoCards: { 158 | id: "infoCards", 159 | default: false, 160 | }, 161 | annotations: { 162 | id: "annotations", 163 | default: true, 164 | }, 165 | endScreen: { 166 | id: "endScreen", 167 | default: false, 168 | }, 169 | autoplayShortcut: { 170 | id: "autoplayShortcut", 171 | default: true, 172 | }, 173 | videoFocusToggle: { 174 | id: "videoFocusToggle", 175 | default: true, 176 | }, 177 | videoScreenshot: { 178 | id: "videoScreenshot", 179 | default: true, 180 | }, 181 | videoThumbnail: { 182 | id: "videoThumbnail", 183 | default: true, 184 | }, 185 | monetizationInfo: { 186 | id: "monetizationInfo", 187 | default: true, 188 | }, 189 | blacklistEnabled: { 190 | id: "blacklistEnabled", 191 | default: true, 192 | }, 193 | blacklistButton: { 194 | id: "blacklistButton", 195 | default: true, 196 | }, 197 | blacklist: { 198 | id: "blacklist", 199 | default: {}, 200 | }, 201 | }; 202 | const getDefaultSettings = () => Object.keys(SettingData).reduce((previousValue, currentValue) => ({ 203 | ...previousValue, 204 | [currentValue]: SettingData[currentValue].default 205 | }), {}); 206 | const defaultSettings = getDefaultSettings(); 207 | 208 | mainScript(extensionId, SettingData, defaultSettings); 209 | 210 | mainScript = undefined; 211 | 212 | })(); -------------------------------------------------------------------------------- /src/chrome/js/content-script.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | globalThis.browser ??= chrome; 4 | 5 | const SettingData = { 6 | extensionButton: { 7 | id: "extensionButton", 8 | default: true, 9 | }, 10 | syncSettings: { 11 | id: "syncSettings", 12 | default: false, 13 | }, 14 | fullTitles: { 15 | id: "fullTitles", 16 | default: true, 17 | }, 18 | theme: { 19 | id: "theme", 20 | default: "deviceTheme", 21 | }, 22 | logoSubscriptions: { 23 | id: "logoSubscriptions", 24 | default: false, 25 | }, 26 | autoplayChannelTrailer: { 27 | id: "autoplayChannelTrailer", 28 | default: false, 29 | }, 30 | channelTab: { 31 | id: "channelTab", 32 | default: "featured", 33 | }, 34 | homeShorts: { 35 | id: "homeShorts", 36 | default: true, 37 | }, 38 | subscriptionsShorts: { 39 | id: "subscriptionsShorts", 40 | default: true, 41 | }, 42 | videoPageShorts: { 43 | id: "videoPageShorts", 44 | default: true, 45 | }, 46 | searchShorts: { 47 | id: "searchShorts", 48 | default: true, 49 | }, 50 | adOptOutAll: { 51 | id: "adOptOutAll", 52 | default: false, 53 | }, 54 | adSubscribed: { 55 | id: "adSubscribed", 56 | default: false, 57 | }, 58 | adVideoFeed: { 59 | id: "adVideoFeed", 60 | default: false, 61 | }, 62 | adInVideo: { 63 | id: "adInVideo", 64 | default: false, 65 | }, 66 | adTaggedProducts: { 67 | id: "adTaggedProducts", 68 | default: false, 69 | }, 70 | adMasthead: { 71 | id: "adMasthead", 72 | default: false, 73 | }, 74 | adHomeFeed: { 75 | id: "adHomeFeed", 76 | default: false, 77 | }, 78 | adSearchFeed: { 79 | id: "adSearchFeed", 80 | default: false, 81 | }, 82 | videoFocus: { 83 | id: "videoFocus", 84 | default: true, 85 | }, 86 | creatorMerch: { 87 | id: "creatorMerch", 88 | default: true, 89 | }, 90 | videoCount: { 91 | id: "videoCount", 92 | default: true, 93 | }, 94 | ambientMode: { 95 | id: "ambientMode", 96 | default: true, 97 | }, 98 | reversePlaylist: { 99 | id: "reversePlaylist", 100 | default: true, 101 | }, 102 | reversePlaylistToggled: { 103 | id: "reversePlaylistToggled", 104 | default: false, 105 | }, 106 | superTheater: { 107 | id: "superTheater", 108 | default: true, 109 | }, 110 | superTheaterScrollbar: { 111 | id: "superTheaterScrollbar", 112 | default: true, 113 | }, 114 | defaultQuality: { 115 | id: "defaultQuality", 116 | default: "auto", 117 | }, 118 | defaultSpeed: { 119 | id: "defaultSpeed", 120 | default: "-1", 121 | }, 122 | alwaysVisible: { 123 | id: "alwaysVisible", 124 | default: true, 125 | }, 126 | alwaysVisiblePosition: { 127 | id: "alwaysVisiblePosition", 128 | default: {}, 129 | }, 130 | hfrAllowed: { 131 | id: "hfrAllowed", 132 | default: true, 133 | }, 134 | autoplay: { 135 | id: "autoplay", 136 | default: false, 137 | }, 138 | loudness: { 139 | id: "loudness", 140 | default: false, 141 | }, 142 | scrollVolume: { 143 | id: "scrollVolume", 144 | default: true, 145 | }, 146 | scrollVolumeShift: { 147 | id: "scrollVolumeShift", 148 | default: true, 149 | }, 150 | scrollVolumeStep: { 151 | id: "scrollVolumeStep", 152 | default: 5, 153 | }, 154 | infoCards: { 155 | id: "infoCards", 156 | default: false, 157 | }, 158 | annotations: { 159 | id: "annotations", 160 | default: true, 161 | }, 162 | endScreen: { 163 | id: "endScreen", 164 | default: false, 165 | }, 166 | autoplayShortcut: { 167 | id: "autoplayShortcut", 168 | default: true, 169 | }, 170 | videoFocusToggle: { 171 | id: "videoFocusToggle", 172 | default: true, 173 | }, 174 | videoScreenshot: { 175 | id: "videoScreenshot", 176 | default: true, 177 | }, 178 | videoThumbnail: { 179 | id: "videoThumbnail", 180 | default: true, 181 | }, 182 | monetizationInfo: { 183 | id: "monetizationInfo", 184 | default: true, 185 | }, 186 | blacklistEnabled: { 187 | id: "blacklistEnabled", 188 | default: true, 189 | }, 190 | blacklistButton: { 191 | id: "blacklistButton", 192 | default: true, 193 | }, 194 | blacklist: { 195 | id: "blacklist", 196 | default: {}, 197 | }, 198 | }; 199 | const getDefaultSettings = () => Object.keys(SettingData).reduce((previousValue, currentValue) => ({ 200 | ...previousValue, 201 | [currentValue]: SettingData[currentValue].default 202 | }), {}); 203 | 204 | const channel = new BroadcastChannel("fdhajofnodmginhfnknimmpdhcgkcldj"); 205 | let port = null; 206 | 207 | const validContext = () => { 208 | 209 | const isValid = !!browser.runtime?.id; 210 | 211 | if (!isValid) { 212 | channel.removeEventListener("message", channelListener); 213 | channel.close(); 214 | } 215 | 216 | return isValid; 217 | 218 | }; 219 | 220 | const channelListener = message => { 221 | 222 | if (!validContext()) { 223 | return; 224 | } 225 | 226 | if (message?.data?.type === "setting") { 227 | saveSettings(message?.data?.payload).then(); 228 | } else if (message?.data?.type === "action") { 229 | portMessage(message?.data); 230 | } 231 | 232 | }; 233 | 234 | const portMessage = data => { 235 | 236 | if (!data) { 237 | return; 238 | } 239 | 240 | if (!validContext()) { 241 | return; 242 | } 243 | 244 | if (!port) { 245 | port = browser.runtime.connect(browser.runtime.id); 246 | port?.onDisconnect?.addListener(() => port = null); 247 | } 248 | 249 | port?.postMessage(data); 250 | 251 | }; 252 | 253 | const saveSettings = async data => { 254 | 255 | if (!data) { 256 | return; 257 | } 258 | 259 | if (!validContext()) { 260 | return; 261 | } 262 | 263 | const dataSync = await browser.storage.sync.get(); 264 | 265 | if (dataSync?.[SettingData.syncSettings.id] === true) { 266 | await browser.storage.sync.set(data); 267 | } else { 268 | await browser.storage.local.set(data); 269 | } 270 | 271 | }; 272 | 273 | const onStorageChanged = changes => { 274 | 275 | if (!validContext()) { 276 | return; 277 | } 278 | 279 | const changeData = {}; 280 | 281 | for (let key in changes) { 282 | 283 | const change = changes[key]; 284 | 285 | if (change.newValue !== change.oldValue) { 286 | changeData[key] = change.newValue; 287 | } 288 | 289 | } 290 | 291 | if (Object.keys(changeData).length > 0) { 292 | 293 | channel.postMessage(changeData); 294 | 295 | // check if user switched storage areas 296 | if (Object.hasOwn(changeData, SettingData.syncSettings.id)) { 297 | if (changeData[SettingData.syncSettings.id] === true) { 298 | browser.storage.local.onChanged.removeListener(onStorageChanged); 299 | browser.storage.sync.onChanged.addListener(onStorageChanged); 300 | } else { 301 | browser.storage.sync.onChanged.removeListener(onStorageChanged); 302 | browser.storage.local.onChanged.addListener(onStorageChanged); 303 | } 304 | } 305 | 306 | } 307 | 308 | }; 309 | 310 | const checkNewFeatures = async settings => { 311 | 312 | const newFeatures = {}; 313 | 314 | for (let key in SettingData) { 315 | if (!Object.hasOwn(settings, key)) { 316 | settings[key] = newFeatures[key] = SettingData[key].default; 317 | } 318 | } 319 | 320 | if (Object.keys(newFeatures).length > 0) { 321 | if (settings[SettingData.syncSettings.id] === true) { 322 | await browser.storage.sync.set(newFeatures); 323 | } else { 324 | await browser.storage.local.set(newFeatures); 325 | } 326 | } 327 | 328 | return settings; 329 | 330 | }; 331 | 332 | const getSettings = async () => { 333 | 334 | const dataSync = await browser.storage.sync.get(); 335 | 336 | if (dataSync?.[SettingData.syncSettings.id] === true) { 337 | return await checkNewFeatures(dataSync); 338 | } 339 | 340 | const dataLocal = await browser.storage.local.get(); 341 | 342 | // storage will be empty during first installation 343 | // this ensures the first load stores the default settings 344 | if (Object.keys(dataLocal).length === 0) { 345 | const defaultSettings = getDefaultSettings(); 346 | await browser.storage.local.set(defaultSettings); 347 | return defaultSettings; 348 | } 349 | 350 | return await checkNewFeatures(dataLocal); 351 | 352 | }; 353 | 354 | channel.addEventListener("message", channelListener); 355 | 356 | browser.storage.sync.get().then(dataSync => { 357 | if (dataSync?.[SettingData.syncSettings.id] === true) { 358 | browser.storage.sync.onChanged.addListener(onStorageChanged); 359 | } else { 360 | browser.storage.local.onChanged.addListener(onStorageChanged); 361 | } 362 | }); 363 | 364 | getSettings().then(settings => channel.postMessage(settings)); -------------------------------------------------------------------------------- /src/chrome/js/service-worker.js: -------------------------------------------------------------------------------- 1 | importScripts("./setting-data.js", "./background.js"); 2 | -------------------------------------------------------------------------------- /src/chrome/js/setting-data.js: -------------------------------------------------------------------------------- 1 | const SettingData = { 2 | extensionButton: { 3 | id: "extensionButton", 4 | default: true, 5 | }, 6 | syncSettings: { 7 | id: "syncSettings", 8 | default: false, 9 | }, 10 | fullTitles: { 11 | id: "fullTitles", 12 | default: true, 13 | }, 14 | theme: { 15 | id: "theme", 16 | default: "deviceTheme", 17 | }, 18 | logoSubscriptions: { 19 | id: "logoSubscriptions", 20 | default: false, 21 | }, 22 | autoplayChannelTrailer: { 23 | id: "autoplayChannelTrailer", 24 | default: false, 25 | }, 26 | channelTab: { 27 | id: "channelTab", 28 | default: "featured", 29 | }, 30 | homeShorts: { 31 | id: "homeShorts", 32 | default: true, 33 | }, 34 | subscriptionsShorts: { 35 | id: "subscriptionsShorts", 36 | default: true, 37 | }, 38 | videoPageShorts: { 39 | id: "videoPageShorts", 40 | default: true, 41 | }, 42 | searchShorts: { 43 | id: "searchShorts", 44 | default: true, 45 | }, 46 | adOptOutAll: { 47 | id: "adOptOutAll", 48 | default: false, 49 | }, 50 | adSubscribed: { 51 | id: "adSubscribed", 52 | default: false, 53 | }, 54 | adVideoFeed: { 55 | id: "adVideoFeed", 56 | default: false, 57 | }, 58 | adInVideo: { 59 | id: "adInVideo", 60 | default: false, 61 | }, 62 | adTaggedProducts: { 63 | id: "adTaggedProducts", 64 | default: false, 65 | }, 66 | adMasthead: { 67 | id: "adMasthead", 68 | default: false, 69 | }, 70 | adHomeFeed: { 71 | id: "adHomeFeed", 72 | default: false, 73 | }, 74 | adSearchFeed: { 75 | id: "adSearchFeed", 76 | default: false, 77 | }, 78 | videoFocus: { 79 | id: "videoFocus", 80 | default: true, 81 | }, 82 | creatorMerch: { 83 | id: "creatorMerch", 84 | default: true, 85 | }, 86 | videoCount: { 87 | id: "videoCount", 88 | default: true, 89 | }, 90 | ambientMode: { 91 | id: "ambientMode", 92 | default: true, 93 | }, 94 | reversePlaylist: { 95 | id: "reversePlaylist", 96 | default: true, 97 | }, 98 | reversePlaylistToggled: { 99 | id: "reversePlaylistToggled", 100 | default: false, 101 | }, 102 | superTheater: { 103 | id: "superTheater", 104 | default: true, 105 | }, 106 | superTheaterScrollbar: { 107 | id: "superTheaterScrollbar", 108 | default: true, 109 | }, 110 | defaultQuality: { 111 | id: "defaultQuality", 112 | default: "auto", 113 | }, 114 | defaultSpeed: { 115 | id: "defaultSpeed", 116 | default: "-1", 117 | }, 118 | alwaysVisible: { 119 | id: "alwaysVisible", 120 | default: true, 121 | }, 122 | alwaysVisiblePosition: { 123 | id: "alwaysVisiblePosition", 124 | default: {}, 125 | }, 126 | hfrAllowed: { 127 | id: "hfrAllowed", 128 | default: true, 129 | }, 130 | autoplay: { 131 | id: "autoplay", 132 | default: false, 133 | }, 134 | loudness: { 135 | id: "loudness", 136 | default: false, 137 | }, 138 | scrollVolume: { 139 | id: "scrollVolume", 140 | default: true, 141 | }, 142 | scrollVolumeShift: { 143 | id: "scrollVolumeShift", 144 | default: true, 145 | }, 146 | scrollVolumeStep: { 147 | id: "scrollVolumeStep", 148 | default: 5, 149 | }, 150 | infoCards: { 151 | id: "infoCards", 152 | default: false, 153 | }, 154 | annotations: { 155 | id: "annotations", 156 | default: true, 157 | }, 158 | endScreen: { 159 | id: "endScreen", 160 | default: false, 161 | }, 162 | autoplayShortcut: { 163 | id: "autoplayShortcut", 164 | default: true, 165 | }, 166 | videoFocusToggle: { 167 | id: "videoFocusToggle", 168 | default: true, 169 | }, 170 | videoScreenshot: { 171 | id: "videoScreenshot", 172 | default: true, 173 | }, 174 | videoThumbnail: { 175 | id: "videoThumbnail", 176 | default: true, 177 | }, 178 | monetizationInfo: { 179 | id: "monetizationInfo", 180 | default: true, 181 | }, 182 | blacklistEnabled: { 183 | id: "blacklistEnabled", 184 | default: true, 185 | }, 186 | blacklistButton: { 187 | id: "blacklistButton", 188 | default: true, 189 | }, 190 | blacklist: { 191 | id: "blacklist", 192 | default: {}, 193 | }, 194 | }; 195 | const getDefaultSettings = () => Object.keys(SettingData).reduce((previousValue, currentValue) => ({ 196 | ...previousValue, 197 | [currentValue]: SettingData[currentValue].default 198 | }), {}); -------------------------------------------------------------------------------- /src/chrome/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "manifest_version": 3, 3 | "name": "Iridium for YouTube", 4 | "version": "2.1.2", 5 | "description": "Take control of YouTube and boost your user experience with Iridium", 6 | "default_locale": "en_US", 7 | "options_ui": { 8 | "page": "html/options.html", 9 | "open_in_tab": true 10 | }, 11 | "icons": { 12 | "16": "icons/16.png", 13 | "32": "icons/32.png", 14 | "48": "icons/48.png", 15 | "64": "icons/64.png", 16 | "128": "icons/128.png" 17 | }, 18 | "permissions": [ 19 | "storage" 20 | ], 21 | "host_permissions": [ 22 | "*://www.youtube.com/*" 23 | ], 24 | "action": { 25 | "default_icon": { 26 | "16": "icons/16.png", 27 | "32": "icons/32.png", 28 | "48": "icons/48.png", 29 | "64": "icons/64.png", 30 | "128": "icons/128.png" 31 | } 32 | }, 33 | "background": { 34 | "service_worker": "js/service-worker.js" 35 | }, 36 | "content_scripts": [ 37 | { 38 | "world": "MAIN", 39 | "matches": [ 40 | "*://www.youtube.com/*" 41 | ], 42 | "css": [ 43 | "css/content-script.css" 44 | ], 45 | "js": [ 46 | "js/background-inject.js", 47 | "js/chrome-wrapper.js" 48 | ], 49 | "run_at": "document_start" 50 | }, 51 | { 52 | "world": "ISOLATED", 53 | "matches": [ 54 | "*://www.youtube.com/*" 55 | ], 56 | "js": [ 57 | "js/content-script.js" 58 | ], 59 | "run_at": "document_start" 60 | } 61 | ] 62 | } 63 | -------------------------------------------------------------------------------- /src/firefox/_locales/en_US/messages.json: -------------------------------------------------------------------------------- 1 | { 2 | "locale_id": { 3 | "message": "English (US)" 4 | }, 5 | "page_title": { 6 | "message": "Iridium" 7 | } 8 | } -------------------------------------------------------------------------------- /src/firefox/css/content-script.css: -------------------------------------------------------------------------------- 1 | /* ini | autoplay */ 2 | #movie_player.unstarted-mode:is(.playing-mode, .paused-mode):not(.buffering-mode, .ytp-player-minimized) > *:not(.ytp-cued-thumbnail-overlay) { 3 | display: none; 4 | } 5 | /* end | autoplay */ 6 | 7 | /* ini | autoplay channel trailer */ 8 | #c4-player.unstarted-mode:is(.playing-mode, .paused-mode):not(.buffering-mode) > *:not(.ytp-cued-thumbnail-overlay) { 9 | display: none; 10 | } 11 | /* end | autoplay channel trailer */ 12 | 13 | /* ini | video focus */ 14 | html #masthead-container, 15 | html #secondary, 16 | html #below { 17 | transition-property: opacity !important; 18 | transition-duration: 0.8s !important;; 19 | transition-timing-function: ease !important;; 20 | transition-delay: 0.25s !important;; 21 | } 22 | html[dim] #masthead-container:not(:hover), 23 | html[dim] #secondary:not(:hover), 24 | html[dim] #below:not(:hover) { 25 | opacity: 0.1; 26 | } 27 | /* end | video focus */ 28 | 29 | /* ini | iridium icon */ 30 | html[dark] .iridium-options yt-icon { 31 | background: #fff; 32 | } 33 | html .iridium-options:hover yt-icon { 34 | background: radial-gradient(circle at 0% 150%, #0ff 35%, #f0f 75%); 35 | } 36 | .iridium-options yt-icon { 37 | mask-image: url('data:image/svg+xml,'); 38 | background: #030303; 39 | } 40 | /* end | iridium icon */ 41 | 42 | /* ini | reverse playlist */ 43 | ytd-toggle-button-renderer:has([aria-label="reversePlaylistButton"]) { 44 | margin-left: 0 !important; 45 | } 46 | html[dark] [aria-label="reversePlaylistButton"] yt-icon { 47 | background: #f1f1f1; 48 | } 49 | [aria-label="reversePlaylistButton"] yt-icon { 50 | background: #0f0f0f; 51 | } 52 | [aria-label="reversePlaylistButton"] yt-icon { 53 | mask-image: url('data:image/svg+xml,'); 54 | } 55 | [aria-label="reversePlaylistButton"][aria-pressed="true"] yt-icon { 56 | mask-image: url('data:image/svg+xml,'); 57 | } 58 | /* end | reverse playlist */ 59 | 60 | /* ini | full titles */ 61 | html.iridium-full-titles #video-title.ytd-video-renderer, 62 | html.iridium-full-titles #video-title.ytd-compact-video-renderer, 63 | html.iridium-full-titles #video-title.ytd-reel-item-renderer, 64 | html.iridium-full-titles #video-title.ytd-rich-grid-media { 65 | max-height: unset; 66 | -webkit-line-clamp: unset; 67 | } 68 | /* end | full titles */ 69 | 70 | /* ini | super theater */ 71 | html[super-theater] #masthead-container.ytd-app:has( > [theater][is-watch-page]) #masthead { 72 | transform: translateY(-100%); 73 | transition: transform .5s ease-out !important; 74 | } 75 | html[super-theater] #masthead-container.ytd-app:has( > [theater][is-watch-page]):hover #masthead { 76 | transform: translateY(0); 77 | } 78 | html[super-theater] ytd-watch-flexy[full-bleed-player]:not([hidden]) #full-bleed-container.ytd-watch-flexy, 79 | html[super-theater] ytd-watch-grid[full-bleed-player]:not([hidden]) #player-full-bleed-container.ytd-watch-grid { 80 | max-height: calc(100vh); 81 | height: calc(100vh); 82 | min-height: unset; 83 | } 84 | html[super-theater] #page-manager.ytd-app:has( > [theater]:not([hidden])) { 85 | margin-top: 0; 86 | } 87 | html[super-theater] #page-manager.ytd-app:has( > [theater]:not([hidden])) ytd-live-chat-frame { 88 | top: 0 !important; 89 | } 90 | html[super-theater] #player-full-bleed-container { 91 | display: flex; 92 | flex-direction: row; 93 | } 94 | html[super-theater] #player-full-bleed-container #player-container { 95 | position: relative; 96 | flex: 1; 97 | } 98 | html[super-theater]:not([super-theater]) #masthead-container.ytd-app, 99 | html[super-theater][super-theater] #masthead-container.ytd-app:not(:has( > [is-watch-page])) { 100 | width: 100% !important; 101 | } 102 | html[super-theater] #page-manager.ytd-app:has( > [theater]:not([hidden])) #chat-container { 103 | position: relative; 104 | } 105 | html[super-theater] #page-manager.ytd-app:has( > [theater]:not([hidden])) ytd-live-chat-frame { 106 | height: 100% !important; 107 | min-height: unset !important; 108 | top: unset !important; 109 | } 110 | /* end | super theater */ 111 | 112 | /* ini | super theater scrollbar */ 113 | html[super-theater][super-theater-scrollbar]:has( ytd-watch-flexy[theater]:not([hidden])) { 114 | scrollbar-width: none; 115 | } 116 | /* end | super theater scrollbar */ 117 | 118 | /* ini | hide end screen cards */ 119 | .iridium-hide-end-screen-cards #movie_player:hover .ytp-ce-element:not(:hover) { 120 | opacity: 0; 121 | } 122 | /* end | hide end screen cards */ 123 | 124 | /* ini | scroll volume */ 125 | #iridium-scroll-volume-level-container { 126 | text-align: center; 127 | position: absolute; 128 | left: 0; 129 | right: 0; 130 | top: 10%; 131 | z-index: 19; 132 | } 133 | #iridium-scroll-volume-level { 134 | display: inline-block; 135 | padding: 10px 20px; 136 | font-size: 175%; 137 | background: rgba(0, 0, 0, .5); 138 | pointer-events: none; 139 | border-radius: 3px; 140 | } 141 | /* end | scroll volume */ 142 | 143 | /* ini | player tools */ 144 | #iridium-player-tools { 145 | display: flex; 146 | align-items: center; 147 | justify-content: center; 148 | font-size: 0; 149 | position: absolute; 150 | top: 0; 151 | right: 0; 152 | bottom: 0; 153 | } 154 | #bottom-grid #iridium-player-tools { 155 | position: unset; 156 | margin-left: auto; 157 | } 158 | #iridium-player-tools > div { 159 | cursor: pointer; 160 | width: 36px; 161 | height: 36px; 162 | justify-content: center; 163 | display: flex; 164 | align-items: center; 165 | fill: var(--yt-spec-text-primary); 166 | position: relative; 167 | } 168 | #iridium-player-tools > div:hover { 169 | background-color: var(--yt-spec-10-percent-layer); 170 | border-radius: 18px; 171 | } 172 | #iridium-player-tools > div > svg { 173 | pointer-events: none; 174 | user-select: none; 175 | } 176 | #iridium-autoplay-shortcut:not([iridium-enabled]) { 177 | opacity: 0.5; 178 | } 179 | #iridium-video-focus:not([iridium-enabled]) #iridium-on, 180 | #iridium-video-focus[iridium-enabled] #iridium-off { 181 | display: none; 182 | } 183 | #iridium-monetization:not(.monetized) .iridium-on, 184 | #iridium-monetization.monetized .iridium-off { 185 | display: none; 186 | } 187 | html[dark] #iridium-player-tools .monetized { 188 | fill: #3fd20a; 189 | } 190 | #iridium-player-tools .monetized { 191 | fill: #3ad406; 192 | } 193 | html[dark] #iridium-player-tools .sponsored { 194 | fill: #3e8bff; 195 | } 196 | #iridium-player-tools .sponsored { 197 | fill: #0677d4; 198 | } 199 | #iridium-monetization-count { 200 | font-size: 10px; 201 | position: absolute; 202 | color: var(--yt-spec-text-primary); 203 | bottom: 0; 204 | right: 0; 205 | background: var(--yt-spec-base-background); 206 | border-radius: 12px; 207 | padding: 0 3px; 208 | } 209 | #iridium-monetization-count { 210 | font-size: 10px; 211 | position: absolute; 212 | color: var(--yt-spec-text-primary); 213 | bottom: 0; 214 | right: 0; 215 | background: var(--yt-spec-base-background); 216 | border-radius: 12px; 217 | padding: 0 3px; 218 | } 219 | #iridium-player-tools > div:hover #iridium-monetization-count { 220 | display: none; 221 | } 222 | /* end | player tools */ 223 | 224 | /* ini | always visible */ 225 | html[always-visible-player] .ytp-miniplayer-button, 226 | html[always-visible-player] .ytp-size-button { 227 | display: none !important; 228 | } 229 | html[always-visible-player]:not(:has(ytd-watch-flexy[fullscreen])) #movie_player { 230 | position: fixed; 231 | z-index: 9999; 232 | height: 225px; 233 | width: 400px; 234 | bottom: 10px; 235 | right: 10px; 236 | box-shadow: 0 4px 5px 0 rgba(0, 0, 0, .14), 0 1px 10px 0 rgba(0, 0, 0, .12), 0 2px 4px -1px rgba(0, 0, 0, .4); 237 | } 238 | html[always-visible-player] #movie_player::before { 239 | background-color: #000; 240 | bottom: 0; 241 | content: ""; 242 | display: block; 243 | left: 0; 244 | position: absolute; 245 | right: 0; 246 | top: 0; 247 | } 248 | html[always-visible-player][moving] #movie_player { 249 | opacity: 0.9; 250 | } 251 | html[always-visible-player][moving] #movie_player::after { 252 | background-color: #fff; 253 | bottom: 0; 254 | content: ""; 255 | display: block; 256 | left: 0; 257 | opacity: .4; 258 | position: absolute; 259 | right: 0; 260 | top: 0; 261 | z-index: 99; 262 | } 263 | html[dark][always-visible-player][moving] #movie_player::after { 264 | background-color: #000; 265 | } 266 | /* end | always visible */ 267 | 268 | /* ini | ambient mode disabled */ 269 | html[ambient-mode-disabled] #cinematics-container { 270 | display: none; 271 | } 272 | /* end | ambient mode disabled */ -------------------------------------------------------------------------------- /src/firefox/css/options.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: "Roboto"; 3 | font-weight: 400; 4 | src: url("../font/Roboto-Regular.ttf"); 5 | } 6 | 7 | @font-face { 8 | font-family: "Roboto"; 9 | font-weight: 500; 10 | src: url("../font/Roboto-Medium.ttf"); 11 | } 12 | 13 | @font-face { 14 | font-family: "Roboto"; 15 | font-weight: 600; 16 | src: url("../font/Roboto-Bold.ttf"); 17 | } 18 | 19 | @keyframes breatheStartEffect { 20 | 0% { 21 | stop-color: #0ff; 22 | } 23 | 50% { 24 | stop-color: var(--logo-color); 25 | } 26 | 100% { 27 | stop-color: #0ff; 28 | } 29 | } 30 | 31 | @keyframes breatheStopEffect { 32 | 0% { 33 | stop-color: #f0f; 34 | } 35 | 50% { 36 | stop-color: var(--logo-color); 37 | } 38 | 100% { 39 | stop-color: #f0f; 40 | } 41 | } 42 | 43 | @keyframes shimmer { 44 | 100% { 45 | mask-position: left 46 | } 47 | } 48 | 49 | html { 50 | --sidebar-width: 240px; 51 | --logo-height: 20px; 52 | --logo-color: #212121; 53 | --link-color: #065fd4; 54 | --background-color: #fff; 55 | --text-color: #0f0f0f; 56 | --text-primary-color: #0f0f0f; 57 | --text-secondary-color: #606060; 58 | --divider-border-color: #0000001a; 59 | --pre-background-color: #00000024; 60 | --item-hover-background-color: #0000000d; 61 | --item-selected-background-color: #0000001a; 62 | --toggle-switch-button-color: #030303; 63 | --toggle-switch-button-active-color: #065fd4; 64 | --toggle-switch-slider-color: #909090; 65 | --dropdown-background-color: #e5e5e5; 66 | --button-background-color: var(--background-color); 67 | --button-background-color-hover: #def1ff; 68 | --button-text-color: var(--toggle-switch-button-active-color); 69 | } 70 | 71 | html[dark] { 72 | --logo-color: #fff; 73 | --link-color: #3ea6ff; 74 | --background-color: #0f0f0f; 75 | --text-color: #f1f1f1; 76 | --text-primary-color: #fff; 77 | --text-secondary-color: #aaa; 78 | --divider-border-color: #fff3; 79 | --pre-background-color: #ffffff24; 80 | --item-hover-background-color: #ffffff1a; 81 | --item-selected-background-color: #fff3; 82 | --toggle-switch-button-color: #fff; 83 | --toggle-switch-button-active-color: #3ea6ff; 84 | --toggle-switch-slider-color: #717171; 85 | --dropdown-background-color: #3f3f3f; 86 | --button-background-color: var(--background-color); 87 | --button-background-color-hover: #263850; 88 | --button-text-color: var(--toggle-switch-button-active-color); 89 | } 90 | 91 | body { 92 | font-family: "Roboto", "Arial", sans-serif; 93 | margin: 0 auto; 94 | position: relative; 95 | background-color: var(--background-color); 96 | height: 100%; 97 | width: 100%; 98 | color: var(--text-color); 99 | } 100 | 101 | a, 102 | .faux-link { 103 | display: inline; 104 | color: var(--link-color) !important; 105 | text-decoration: none; 106 | cursor: pointer; 107 | } 108 | 109 | :focus { 110 | outline: none; 111 | } 112 | 113 | ::-moz-focus-inner { 114 | border: 0; 115 | } 116 | 117 | [hidden] { 118 | display: none; 119 | } 120 | 121 | pre { 122 | display: inline; 123 | background: var(--pre-background-color); 124 | padding: 2px 6px; 125 | border-radius: 4px; 126 | } 127 | 128 | #version { 129 | position: fixed; 130 | bottom: 0; 131 | right: 0; 132 | opacity: 0.5; 133 | font-size: 12px; 134 | padding: 6px 12px; 135 | user-select: none; 136 | pointer-events: none; 137 | } 138 | 139 | .shimmer { 140 | mask: linear-gradient(-60deg, #000 30%, #0005, #000 70%) right/400% 100%; 141 | background-repeat: no-repeat; 142 | animation: shimmer 2.5s infinite; 143 | width: fit-content; 144 | } 145 | 146 | .borderBottom { 147 | border-bottom: 1px solid var(--divider-border-color); 148 | } 149 | 150 | #title { 151 | width: var(--sidebar-width); 152 | font-size: 0; 153 | text-align: center; 154 | } 155 | 156 | #logo { 157 | height: var(--logo-height); 158 | padding: 0 16px; 159 | margin: 18px 12px; 160 | } 161 | 162 | #logo .name path { 163 | fill: var(--logo-color); 164 | } 165 | 166 | .logo-start-gradient { 167 | animation: breatheStartEffect 5s linear infinite; 168 | } 169 | 170 | .logo-stop-gradient { 171 | animation: breatheStopEffect 5s linear infinite; 172 | } 173 | 174 | #container { 175 | display: flex; 176 | } 177 | 178 | #menu { 179 | width: var(--sidebar-width); 180 | min-width: var(--sidebar-width); 181 | padding: 18px 0; 182 | } 183 | 184 | .item { 185 | height: 40px; 186 | margin: 0 12px; 187 | border-radius: 10px; 188 | cursor: pointer; 189 | user-select: none; 190 | padding: 0 16px; 191 | text-overflow: ellipsis; 192 | display: block; 193 | overflow: hidden; 194 | white-space: nowrap; 195 | font-size: 14px; 196 | line-height: 40px; 197 | font-weight: 400; 198 | } 199 | 200 | .item:hover { 201 | background-color: var(--item-hover-background-color); 202 | } 203 | 204 | .item[data-active] { 205 | background-color: var(--item-selected-background-color); 206 | font-weight: 500; 207 | } 208 | 209 | #contents { 210 | padding: 18px 32px; 211 | max-width: 1000px; 212 | flex-grow: 1; 213 | margin: 0 auto; 214 | } 215 | 216 | .content:not([data-active]) { 217 | display: none; 218 | } 219 | 220 | .contentTitle { 221 | line-height: 40px; 222 | font-size: 20px; 223 | font-weight: 500; 224 | } 225 | 226 | .contentDescription { 227 | color: var(--text-secondary-color); 228 | font-size: 12px; 229 | padding-bottom: 24px; 230 | margin-bottom: 24px; 231 | } 232 | 233 | .settingGroup { 234 | display: flex; 235 | } 236 | 237 | .settingLabel { 238 | color: var(--text-color); 239 | font-size: 14px; 240 | font-weight: 500; 241 | width: 160px; 242 | min-width: 160px; 243 | margin-right: 56px; 244 | } 245 | 246 | .setting { 247 | width: 100%; 248 | display: flex; 249 | margin-bottom: 24px; 250 | transition: opacity .08s; 251 | cursor: default; 252 | } 253 | 254 | .setting.disabled { 255 | opacity: 0.4; 256 | user-select: none; 257 | pointer-events: none; 258 | } 259 | 260 | .setting select { 261 | font-family: "Roboto", "Arial", sans-serif; 262 | font-size: 14px; 263 | font-weight: 500; 264 | padding: 8px 16px; 265 | background-color: var(--dropdown-background-color); 266 | color: var(--text-primary-color); 267 | border-radius: 6px; 268 | border: 0 none; 269 | margin-bottom: 6px; 270 | min-width: 120px; 271 | } 272 | 273 | .settingDescription { 274 | } 275 | 276 | .settingDescription.highlight { 277 | color: var(--text-primary-color); 278 | font-size: 14px; 279 | font-weight: 500; 280 | margin-bottom: 4px; 281 | } 282 | 283 | .settingDescription:not(.highlight) { 284 | color: var(--text-secondary-color); 285 | font-size: 14px; 286 | font-weight: 400; 287 | } 288 | 289 | .switch { 290 | position: relative; 291 | display: flex; 292 | width: 38px; 293 | height: 20px; 294 | min-width: 38px; 295 | padding-right: 20px; 296 | } 297 | 298 | .switch input { 299 | opacity: 0; 300 | width: 0; 301 | height: 0; 302 | pointer-events: none; 303 | } 304 | 305 | .slider { 306 | position: absolute; 307 | top: 0; 308 | left: 0; 309 | right: 0; 310 | bottom: 0; 311 | pointer-events: none; 312 | } 313 | 314 | .slider::before { 315 | position: absolute; 316 | content: ""; 317 | background-color: var(--toggle-switch-slider-color); 318 | opacity: 0.4; 319 | height: 14px; 320 | width: 36px; 321 | transition: .08s; 322 | margin: 3px 1px; 323 | border-radius: 8px; 324 | } 325 | 326 | .slider::after { 327 | position: absolute; 328 | box-shadow: 0 1px 5px 0 rgba(0, 0, 0, 0.6); 329 | content: ""; 330 | height: 20px; 331 | width: 20px; 332 | background-color: var(--toggle-switch-button-color); 333 | transition: .08s; 334 | top: 0; 335 | left: 0; 336 | border-radius: 50%; 337 | } 338 | 339 | input:checked + .slider::after { 340 | background-color: var(--toggle-switch-button-active-color); 341 | left: 18px; 342 | } 343 | 344 | .radioGroup { 345 | margin: 0 0 24px; 346 | padding: 0; 347 | border: none; 348 | color: var(--text-secondary-color); 349 | } 350 | 351 | .radio { 352 | --radio-width: 20px; 353 | font-size: 16px; 354 | position: relative; 355 | display: flex; 356 | height: 20px; 357 | min-width: var(--radio-width); 358 | min-height: 20px; 359 | padding-left: calc(var(--radio-width) + 16px); 360 | margin-bottom: 20px; 361 | } 362 | 363 | .radio input { 364 | opacity: 0; 365 | width: 0; 366 | height: 0; 367 | pointer-events: none; 368 | display: none; 369 | } 370 | 371 | .radio .button::before { 372 | position: absolute; 373 | content: ""; 374 | border: 2px solid var(--toggle-switch-button-color); 375 | height: 20px; 376 | width: 20px; 377 | left: 0; 378 | transition: .08s; 379 | box-sizing: border-box; 380 | border-radius: 50%; 381 | } 382 | 383 | .radio .button::after { 384 | position: absolute; 385 | content: ""; 386 | background-color: var(--toggle-switch-button-color); 387 | height: 10px; 388 | width: 10px; 389 | left: 5px; 390 | top: 0; 391 | bottom: 0; 392 | margin: auto; 393 | transition: .08s; 394 | box-sizing: border-box; 395 | border-radius: 50%; 396 | transform: scale(0); 397 | } 398 | 399 | input:checked + .button::before { 400 | border-color: var(--toggle-switch-button-active-color); 401 | } 402 | 403 | input:checked + .button::after { 404 | background-color: var(--toggle-switch-button-active-color); 405 | transform: scale(1); 406 | } 407 | 408 | #blacklistControls { 409 | display: flex; 410 | margin-bottom: 12px; 411 | gap: 16px; 412 | align-items: center; 413 | font-size: 14px; 414 | font-weight: 500; 415 | justify-content: space-between; 416 | } 417 | 418 | #filterChannelsContainer { 419 | position: relative; 420 | line-height: 46px; 421 | padding: 0 16px; 422 | } 423 | 424 | #filterChannelsContainer::before { 425 | position: absolute; 426 | content: ""; 427 | top: 0; 428 | bottom: 0; 429 | left: 0; 430 | right: 0; 431 | border-radius: 12px; 432 | border: 1px solid var(--divider-border-color); 433 | } 434 | 435 | #filterChannels { 436 | font-family: "Roboto", "Arial", sans-serif; 437 | position: relative; 438 | background: var(--background-color); 439 | color: var(--text-color); 440 | border: none; 441 | font-size: 14px; 442 | font-weight: 500; 443 | } 444 | 445 | #blacklistChannels { 446 | padding: 8px; 447 | position: relative; 448 | display: flex; 449 | flex-wrap: wrap; 450 | gap: 8px; 451 | line-height: 36px; 452 | } 453 | 454 | #blacklistChannels::before { 455 | position: absolute; 456 | content: ""; 457 | border-radius: 10px; 458 | background: var(--toggle-switch-slider-color); 459 | opacity: 0.1; 460 | top: 0; 461 | bottom: 0; 462 | left: 0; 463 | right: 0; 464 | z-index: -1; 465 | } 466 | 467 | #blacklistActions { 468 | display: flex; 469 | gap: 16px; 470 | align-items: center; 471 | } 472 | 473 | .action-button { 474 | background-color: var(--button-background-color); 475 | color: var(--button-text-color); 476 | font-size: 14px; 477 | font-weight: 500; 478 | border-radius: 100px; 479 | text-align: center; 480 | padding: 10px 16px; 481 | cursor: pointer; 482 | user-select: none; 483 | border: 1px solid var(--divider-border-color); 484 | text-transform: uppercase; 485 | } 486 | 487 | .action-button:not(.disabled):hover { 488 | background-color: var(--button-background-color-hover); 489 | border-color: transparent; 490 | } 491 | 492 | .action-button.disabled { 493 | pointer-events: none; 494 | filter: grayscale(1); 495 | } 496 | 497 | .channel { 498 | position: relative; 499 | display: flex; 500 | align-items: center; 501 | width: fit-content; 502 | padding: 0 16px; 503 | background: var(--item-selected-background-color); 504 | border-radius: 10px; 505 | font-weight: 500; 506 | cursor: pointer; 507 | line-height: 36px; 508 | min-width: 60px; 509 | justify-content: center; 510 | } 511 | 512 | .remove { 513 | position: absolute; 514 | left: 0; 515 | right: 0; 516 | margin: 0 auto; 517 | fill: var(--text-color); 518 | transition: 0.2s; 519 | user-select: none; 520 | pointer-events: none; 521 | } 522 | 523 | .channel:not(:hover) .remove { 524 | opacity: 0; 525 | } 526 | 527 | .channelName { 528 | transition: 0.2s; 529 | user-select: none; 530 | pointer-events: none; 531 | } 532 | 533 | .channel:hover .channelName { 534 | opacity: 0.2; 535 | } 536 | 537 | #backdrop { 538 | position: fixed; 539 | top: 0; 540 | bottom: 0; 541 | left: 0; 542 | right: 0; 543 | display: flex; 544 | align-items: center; 545 | justify-content: center; 546 | } 547 | 548 | #backdrop::before { 549 | position: absolute; 550 | content: ""; 551 | background-color: var(--button-background-color); 552 | opacity: 0.9; 553 | top: 0; 554 | bottom: 0; 555 | left: 0; 556 | right: 0; 557 | z-index: -1; 558 | } 559 | 560 | #dialog { 561 | background-color: var(--background-color); 562 | min-width: 400px; 563 | padding: 24px; 564 | border-radius: 20px; 565 | box-shadow: 0 5px 20px black; 566 | display: flex; 567 | flex-direction: column; 568 | gap: 16px; 569 | } 570 | 571 | #dialog input { 572 | font-family: "Roboto", "Arial", sans-serif; 573 | background-color: var(--background-color); 574 | font-size: 16px; 575 | border-radius: 8px; 576 | line-height: 26px; 577 | padding: 4px 8px; 578 | flex: 1; 579 | color: var(--text-color); 580 | border: 1px solid var(--divider-border-color); 581 | } 582 | 583 | #searchForm { 584 | display: flex; 585 | gap: 16px; 586 | color: var(--text-secondary-color); 587 | } 588 | 589 | #searchResult { 590 | position: relative; 591 | display: flex; 592 | align-items: center; 593 | padding: 16px; 594 | flex-flow: column; 595 | gap: 8px; 596 | } 597 | 598 | #searchResult::before { 599 | position: absolute; 600 | content: ""; 601 | background: var(--toggle-switch-slider-color); 602 | opacity: 0.1; 603 | top: 0; 604 | bottom: 0; 605 | left: 0; 606 | right: 0; 607 | border-radius: 10px; 608 | user-select: none; 609 | pointer-events: none; 610 | } 611 | 612 | #searchResult > div { 613 | z-index: 0; 614 | } 615 | 616 | #searchChannelAvatarContainer { 617 | border-radius: 100%; 618 | width: 64px; 619 | height: 64px; 620 | overflow: hidden; 621 | } 622 | 623 | #searchChannelName { 624 | border-radius: 4px; 625 | font-weight: 500; 626 | } 627 | 628 | #searchResultMessage { 629 | position: absolute; 630 | opacity: 1; 631 | top: 0; 632 | bottom: 0; 633 | margin: 0 auto; 634 | display: flex; 635 | align-items: center; 636 | } 637 | 638 | #searchChannelAvatar { 639 | height: 100%; 640 | width: 100%; 641 | } 642 | 643 | #dialog:not(.noResults) #searchResultMessage { 644 | display: none; 645 | } 646 | 647 | #dialog.noResults #searchChannelAvatarContainer, 648 | #dialog.noResults #searchChannelName { 649 | opacity: 0; 650 | user-select: none; 651 | pointer-events: none; 652 | } 653 | 654 | #blockedIndicator { 655 | color: var(--background-color); 656 | font-size: 10px; 657 | font-weight: 500; 658 | margin-top: -20px; 659 | background: var(--link-color); 660 | padding: 2px 4px; 661 | border-radius: 4px; 662 | user-select: none; 663 | pointer-events: none; 664 | } 665 | 666 | #dialog:not(.channelBlocked) #blockedIndicator { 667 | opacity: 0; 668 | } 669 | 670 | #dialogAction { 671 | display: flex; 672 | gap: 16px; 673 | justify-content: center; 674 | } 675 | 676 | #dialog:not(.noResults) #addDialog:hover, 677 | #dialog:not(.channelBlocked) #addDialog:hover { 678 | background-color: var(--button-background-color-hover); 679 | border-color: transparent; 680 | } 681 | 682 | #dialog.noResults #addDialog, 683 | #dialog.channelBlocked #addDialog { 684 | pointer-events: none; 685 | filter: grayscale(1); 686 | } -------------------------------------------------------------------------------- /src/firefox/font/LICENSE.txt: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /src/firefox/font/Roboto-Black.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ParticleCore/Iridium/be0acb55146aac60c34eef3fe22f3dda407aa2fa/src/firefox/font/Roboto-Black.ttf -------------------------------------------------------------------------------- /src/firefox/font/Roboto-BlackItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ParticleCore/Iridium/be0acb55146aac60c34eef3fe22f3dda407aa2fa/src/firefox/font/Roboto-BlackItalic.ttf -------------------------------------------------------------------------------- /src/firefox/font/Roboto-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ParticleCore/Iridium/be0acb55146aac60c34eef3fe22f3dda407aa2fa/src/firefox/font/Roboto-Bold.ttf -------------------------------------------------------------------------------- /src/firefox/font/Roboto-BoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ParticleCore/Iridium/be0acb55146aac60c34eef3fe22f3dda407aa2fa/src/firefox/font/Roboto-BoldItalic.ttf -------------------------------------------------------------------------------- /src/firefox/font/Roboto-Italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ParticleCore/Iridium/be0acb55146aac60c34eef3fe22f3dda407aa2fa/src/firefox/font/Roboto-Italic.ttf -------------------------------------------------------------------------------- /src/firefox/font/Roboto-Light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ParticleCore/Iridium/be0acb55146aac60c34eef3fe22f3dda407aa2fa/src/firefox/font/Roboto-Light.ttf -------------------------------------------------------------------------------- /src/firefox/font/Roboto-LightItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ParticleCore/Iridium/be0acb55146aac60c34eef3fe22f3dda407aa2fa/src/firefox/font/Roboto-LightItalic.ttf -------------------------------------------------------------------------------- /src/firefox/font/Roboto-Medium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ParticleCore/Iridium/be0acb55146aac60c34eef3fe22f3dda407aa2fa/src/firefox/font/Roboto-Medium.ttf -------------------------------------------------------------------------------- /src/firefox/font/Roboto-MediumItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ParticleCore/Iridium/be0acb55146aac60c34eef3fe22f3dda407aa2fa/src/firefox/font/Roboto-MediumItalic.ttf -------------------------------------------------------------------------------- /src/firefox/font/Roboto-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ParticleCore/Iridium/be0acb55146aac60c34eef3fe22f3dda407aa2fa/src/firefox/font/Roboto-Regular.ttf -------------------------------------------------------------------------------- /src/firefox/font/Roboto-Thin.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ParticleCore/Iridium/be0acb55146aac60c34eef3fe22f3dda407aa2fa/src/firefox/font/Roboto-Thin.ttf -------------------------------------------------------------------------------- /src/firefox/font/Roboto-ThinItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ParticleCore/Iridium/be0acb55146aac60c34eef3fe22f3dda407aa2fa/src/firefox/font/Roboto-ThinItalic.ttf -------------------------------------------------------------------------------- /src/firefox/icons/128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ParticleCore/Iridium/be0acb55146aac60c34eef3fe22f3dda407aa2fa/src/firefox/icons/128.png -------------------------------------------------------------------------------- /src/firefox/icons/144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ParticleCore/Iridium/be0acb55146aac60c34eef3fe22f3dda407aa2fa/src/firefox/icons/144.png -------------------------------------------------------------------------------- /src/firefox/icons/16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ParticleCore/Iridium/be0acb55146aac60c34eef3fe22f3dda407aa2fa/src/firefox/icons/16.png -------------------------------------------------------------------------------- /src/firefox/icons/32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ParticleCore/Iridium/be0acb55146aac60c34eef3fe22f3dda407aa2fa/src/firefox/icons/32.png -------------------------------------------------------------------------------- /src/firefox/icons/48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ParticleCore/Iridium/be0acb55146aac60c34eef3fe22f3dda407aa2fa/src/firefox/icons/48.png -------------------------------------------------------------------------------- /src/firefox/icons/64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ParticleCore/Iridium/be0acb55146aac60c34eef3fe22f3dda407aa2fa/src/firefox/icons/64.png -------------------------------------------------------------------------------- /src/firefox/icons/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ParticleCore/Iridium/be0acb55146aac60c34eef3fe22f3dda407aa2fa/src/firefox/icons/favicon.ico -------------------------------------------------------------------------------- /src/firefox/img/iridium.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /src/firefox/js/background.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | globalThis.browser ??= chrome; 4 | 5 | const openOptions = () => { 6 | browser.runtime.openOptionsPage()?.then?.(); 7 | } 8 | const Api = { 9 | debounce: false, 10 | onMessageListener: (data) => { 11 | 12 | if (!data.type || !data.payload || Api.debounce) { 13 | return; 14 | } 15 | 16 | // prevents the options page from opening in duplicate 17 | Api.debounce = true; 18 | setTimeout(() => Api.debounce = false, 1000); 19 | 20 | if (data.payload === SettingData.extensionButton.id) { 21 | openOptions(); 22 | } 23 | 24 | } 25 | } 26 | const onConnect = (port) => { 27 | port.onMessage.addListener(Api.onMessageListener); 28 | } 29 | 30 | browser.runtime.onConnect.addListener(onConnect); 31 | // firefox mv2 32 | browser.browserAction.onClicked.addListener(openOptions); -------------------------------------------------------------------------------- /src/firefox/js/content-script.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const channel = new BroadcastChannel(browser.runtime.id); 4 | let port = null; 5 | 6 | const validContext = () => { 7 | 8 | const isValid = !!browser.runtime?.id; 9 | 10 | if (!isValid) { 11 | channel.removeEventListener("message", channelListener); 12 | channel.close(); 13 | } 14 | 15 | return isValid; 16 | 17 | }; 18 | 19 | const channelListener = message => { 20 | 21 | if (!validContext()) { 22 | return; 23 | } 24 | 25 | if (message?.data?.type === "setting") { 26 | saveSettings(message?.data?.payload).then(); 27 | } else if (message?.data?.type === "action") { 28 | portMessage(message?.data); 29 | } 30 | 31 | }; 32 | 33 | const portMessage = data => { 34 | 35 | if (!data) { 36 | return; 37 | } 38 | 39 | if (!validContext()) { 40 | return; 41 | } 42 | 43 | if (!port) { 44 | port = browser.runtime.connect(browser.runtime.id); 45 | port?.onDisconnect?.addListener(() => port = null); 46 | } 47 | 48 | port?.postMessage(data); 49 | 50 | }; 51 | 52 | const saveSettings = async data => { 53 | 54 | if (!data) { 55 | return; 56 | } 57 | 58 | if (!validContext()) { 59 | return; 60 | } 61 | 62 | const dataSync = await browser.storage.sync.get(); 63 | 64 | if (dataSync?.[SettingData.syncSettings.id] === true) { 65 | await browser.storage.sync.set(data); 66 | } else { 67 | await browser.storage.local.set(data); 68 | } 69 | 70 | }; 71 | 72 | const onStorageChanged = changes => { 73 | 74 | if (!validContext()) { 75 | return; 76 | } 77 | 78 | const changeData = {}; 79 | 80 | for (let key in changes) { 81 | 82 | const change = changes[key]; 83 | 84 | if (change.newValue !== change.oldValue) { 85 | changeData[key] = change.newValue; 86 | } 87 | 88 | } 89 | 90 | if (Object.keys(changeData).length > 0) { 91 | 92 | channel.postMessage(changeData); 93 | 94 | // check if user switched storage areas 95 | if (Object.hasOwn(changeData, SettingData.syncSettings.id)) { 96 | if (changeData[SettingData.syncSettings.id] === true) { 97 | browser.storage.local.onChanged.removeListener(onStorageChanged); 98 | browser.storage.sync.onChanged.addListener(onStorageChanged); 99 | } else { 100 | browser.storage.sync.onChanged.removeListener(onStorageChanged); 101 | browser.storage.local.onChanged.addListener(onStorageChanged); 102 | } 103 | } 104 | 105 | } 106 | 107 | }; 108 | 109 | const checkNewFeatures = async settings => { 110 | 111 | const newFeatures = {}; 112 | 113 | for (let key in SettingData) { 114 | if (!Object.hasOwn(settings, key)) { 115 | settings[key] = newFeatures[key] = SettingData[key].default; 116 | } 117 | } 118 | 119 | if (Object.keys(newFeatures).length > 0) { 120 | if (settings[SettingData.syncSettings.id] === true) { 121 | await browser.storage.sync.set(newFeatures); 122 | } else { 123 | await browser.storage.local.set(newFeatures); 124 | } 125 | } 126 | 127 | return settings; 128 | 129 | }; 130 | 131 | const getSettings = async () => { 132 | 133 | const dataSync = await browser.storage.sync.get(); 134 | 135 | if (dataSync?.[SettingData.syncSettings.id] === true) { 136 | return await checkNewFeatures(dataSync); 137 | } 138 | 139 | const dataLocal = await browser.storage.local.get(); 140 | 141 | // storage will be empty during first installation 142 | // this ensures the first load stores the default settings 143 | if (Object.keys(dataLocal).length === 0) { 144 | const defaultSettings = getDefaultSettings(); 145 | await browser.storage.local.set(defaultSettings); 146 | return defaultSettings; 147 | } 148 | 149 | return await checkNewFeatures(dataLocal); 150 | 151 | }; 152 | 153 | channel.addEventListener("message", channelListener); 154 | 155 | browser.storage.sync.get().then(dataSync => { 156 | if (dataSync?.[SettingData.syncSettings.id] === true) { 157 | browser.storage.sync.onChanged.addListener(onStorageChanged); 158 | } else { 159 | browser.storage.local.onChanged.addListener(onStorageChanged); 160 | } 161 | }); 162 | 163 | getSettings().then(settings => channel.postMessage(settings)); 164 | 165 | if (!document.getElementById("iridium-inject")) { 166 | const script = document.createElement("script"); 167 | script.id = "iridium-inject"; 168 | script.textContent = `(${mainScript}("${browser.runtime.id}",${JSON.stringify(SettingData)},${JSON.stringify(getDefaultSettings())}))`; 169 | document.documentElement.appendChild(script); 170 | } -------------------------------------------------------------------------------- /src/firefox/js/setting-data.js: -------------------------------------------------------------------------------- 1 | const SettingData = { 2 | extensionButton: { 3 | id: "extensionButton", 4 | default: true, 5 | }, 6 | syncSettings: { 7 | id: "syncSettings", 8 | default: false, 9 | }, 10 | fullTitles: { 11 | id: "fullTitles", 12 | default: true, 13 | }, 14 | theme: { 15 | id: "theme", 16 | default: "deviceTheme", 17 | }, 18 | logoSubscriptions: { 19 | id: "logoSubscriptions", 20 | default: false, 21 | }, 22 | autoplayChannelTrailer: { 23 | id: "autoplayChannelTrailer", 24 | default: false, 25 | }, 26 | channelTab: { 27 | id: "channelTab", 28 | default: "featured", 29 | }, 30 | homeShorts: { 31 | id: "homeShorts", 32 | default: true, 33 | }, 34 | subscriptionsShorts: { 35 | id: "subscriptionsShorts", 36 | default: true, 37 | }, 38 | videoPageShorts: { 39 | id: "videoPageShorts", 40 | default: true, 41 | }, 42 | searchShorts: { 43 | id: "searchShorts", 44 | default: true, 45 | }, 46 | adOptOutAll: { 47 | id: "adOptOutAll", 48 | default: false, 49 | }, 50 | adSubscribed: { 51 | id: "adSubscribed", 52 | default: false, 53 | }, 54 | adVideoFeed: { 55 | id: "adVideoFeed", 56 | default: false, 57 | }, 58 | adInVideo: { 59 | id: "adInVideo", 60 | default: false, 61 | }, 62 | adTaggedProducts: { 63 | id: "adTaggedProducts", 64 | default: false, 65 | }, 66 | adMasthead: { 67 | id: "adMasthead", 68 | default: false, 69 | }, 70 | adHomeFeed: { 71 | id: "adHomeFeed", 72 | default: false, 73 | }, 74 | adSearchFeed: { 75 | id: "adSearchFeed", 76 | default: false, 77 | }, 78 | videoFocus: { 79 | id: "videoFocus", 80 | default: true, 81 | }, 82 | creatorMerch: { 83 | id: "creatorMerch", 84 | default: true, 85 | }, 86 | videoCount: { 87 | id: "videoCount", 88 | default: true, 89 | }, 90 | ambientMode: { 91 | id: "ambientMode", 92 | default: true, 93 | }, 94 | reversePlaylist: { 95 | id: "reversePlaylist", 96 | default: true, 97 | }, 98 | reversePlaylistToggled: { 99 | id: "reversePlaylistToggled", 100 | default: false, 101 | }, 102 | superTheater: { 103 | id: "superTheater", 104 | default: true, 105 | }, 106 | superTheaterScrollbar: { 107 | id: "superTheaterScrollbar", 108 | default: true, 109 | }, 110 | defaultQuality: { 111 | id: "defaultQuality", 112 | default: "auto", 113 | }, 114 | defaultSpeed: { 115 | id: "defaultSpeed", 116 | default: "-1", 117 | }, 118 | alwaysVisible: { 119 | id: "alwaysVisible", 120 | default: true, 121 | }, 122 | alwaysVisiblePosition: { 123 | id: "alwaysVisiblePosition", 124 | default: {}, 125 | }, 126 | hfrAllowed: { 127 | id: "hfrAllowed", 128 | default: true, 129 | }, 130 | autoplay: { 131 | id: "autoplay", 132 | default: false, 133 | }, 134 | loudness: { 135 | id: "loudness", 136 | default: false, 137 | }, 138 | scrollVolume: { 139 | id: "scrollVolume", 140 | default: true, 141 | }, 142 | scrollVolumeShift: { 143 | id: "scrollVolumeShift", 144 | default: true, 145 | }, 146 | scrollVolumeStep: { 147 | id: "scrollVolumeStep", 148 | default: 5, 149 | }, 150 | infoCards: { 151 | id: "infoCards", 152 | default: false, 153 | }, 154 | annotations: { 155 | id: "annotations", 156 | default: true, 157 | }, 158 | endScreen: { 159 | id: "endScreen", 160 | default: false, 161 | }, 162 | autoplayShortcut: { 163 | id: "autoplayShortcut", 164 | default: true, 165 | }, 166 | videoFocusToggle: { 167 | id: "videoFocusToggle", 168 | default: true, 169 | }, 170 | videoScreenshot: { 171 | id: "videoScreenshot", 172 | default: true, 173 | }, 174 | videoThumbnail: { 175 | id: "videoThumbnail", 176 | default: true, 177 | }, 178 | monetizationInfo: { 179 | id: "monetizationInfo", 180 | default: true, 181 | }, 182 | blacklistEnabled: { 183 | id: "blacklistEnabled", 184 | default: true, 185 | }, 186 | blacklistButton: { 187 | id: "blacklistButton", 188 | default: true, 189 | }, 190 | blacklist: { 191 | id: "blacklist", 192 | default: {}, 193 | }, 194 | }; 195 | const getDefaultSettings = () => Object.keys(SettingData).reduce((previousValue, currentValue) => ({ 196 | ...previousValue, 197 | [currentValue]: SettingData[currentValue].default 198 | }), {}); -------------------------------------------------------------------------------- /src/firefox/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "manifest_version": 2, 3 | "name": "Iridium for YouTube", 4 | "version": "2.1.2", 5 | "description": "Take control of YouTube and boost your user experience with Iridium", 6 | "default_locale": "en_US", 7 | "options_ui": { 8 | "page": "html/options.html", 9 | "open_in_tab": true 10 | }, 11 | "icons": { 12 | "16": "icons/16.png", 13 | "32": "icons/32.png", 14 | "48": "icons/48.png", 15 | "64": "icons/64.png", 16 | "128": "icons/128.png" 17 | }, 18 | "permissions": [ 19 | "storage", 20 | "*://www.youtube.com/*" 21 | ], 22 | "browser_action": { 23 | "default_icon": { 24 | "16": "icons/16.png", 25 | "32": "icons/32.png", 26 | "48": "icons/48.png", 27 | "64": "icons/64.png", 28 | "128": "icons/128.png" 29 | } 30 | }, 31 | "background": { 32 | "scripts": [ 33 | "js/setting-data.js", 34 | "js/background.js" 35 | ], 36 | "persistent": false 37 | }, 38 | "content_scripts": [ 39 | { 40 | "matches": [ 41 | "*://www.youtube.com/*" 42 | ], 43 | "css": [ 44 | "css/content-script.css" 45 | ], 46 | "js": [ 47 | "js/setting-data.js", 48 | "js/background-inject.js", 49 | "js/content-script.js" 50 | ], 51 | "run_at": "document_start" 52 | } 53 | ], 54 | "browser_specific_settings": { 55 | "gecko": { 56 | "id": "unlisted-iridium@particlecore.github.io", 57 | "strict_min_version": "110.0", 58 | "update_url": "https://github.com/ParticleCore/Iridium/raw/master/bin/update.json" 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /types/chrome-types/LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /types/chrome-types/README.md: -------------------------------------------------------------------------------- 1 | Published TypeScript definition files for Chrome Extensions, automatically generated from Chromium source code. 2 | 3 | The default types file "index.d.ts" contains MV3+ types only. 4 | 5 | The helper "_all.d.ts" contains types including the deprecated Platform Apps APIs, and is used for the developer.chrome.com site. 6 | -------------------------------------------------------------------------------- /types/chrome-types/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "TypeScript definitions for Chrome extensions", 3 | "license": "Apache-2.0", 4 | "types": "index.d.ts", 5 | "type": "module", 6 | "name": "chrome-types", 7 | "config": { 8 | "build-hash": "7b9ad915b95393b2" 9 | }, 10 | "repository": { 11 | "type": "git", 12 | "url": "git+https://github.com/GoogleChrome/chrome-types.git" 13 | }, 14 | "author": "The Chromium Authors", 15 | "bugs": { 16 | "url": "https://github.com/GoogleChrome/chrome-types/issues" 17 | }, 18 | "homepage": "https://github.com/GoogleChrome/chrome-types", 19 | "version": "0.1.263" 20 | } --------------------------------------------------------------------------------