├── LICENSE ├── README.md ├── manifest.json └── src ├── js ├── content.js └── data-storage.js ├── png ├── icon144.png ├── icon20.png ├── icon256.png ├── icon48.png ├── icon512.png └── mtiguide.png ├── popup ├── popup.css ├── popup.html └── popup.js └── svg └── icon256.svg /LICENSE: -------------------------------------------------------------------------------- 1 | Attribution-NonCommercial-ShareAlike 4.0 International 2 | 3 | ======================================================================= 4 | 5 | Creative Commons Corporation ("Creative Commons") is not a law firm and 6 | does not provide legal services or legal advice. Distribution of 7 | Creative Commons public licenses does not create a lawyer-client or 8 | other relationship. Creative Commons makes its licenses and related 9 | information available on an "as-is" basis. Creative Commons gives no 10 | warranties regarding its licenses, any material licensed under their 11 | terms and conditions, or any related information. Creative Commons 12 | disclaims all liability for damages resulting from their use to the 13 | fullest extent possible. 14 | 15 | Using Creative Commons Public Licenses 16 | 17 | Creative Commons public licenses provide a standard set of terms and 18 | conditions that creators and other rights holders may use to share 19 | original works of authorship and other material subject to copyright 20 | and certain other rights specified in the public license below. The 21 | following considerations are for informational purposes only, are not 22 | exhaustive, and do not form part of our licenses. 23 | 24 | Considerations for licensors: Our public licenses are 25 | intended for use by those authorized to give the public 26 | permission to use material in ways otherwise restricted by 27 | copyright and certain other rights. Our licenses are 28 | irrevocable. Licensors should read and understand the terms 29 | and conditions of the license they choose before applying it. 30 | Licensors should also secure all rights necessary before 31 | applying our licenses so that the public can reuse the 32 | material as expected. Licensors should clearly mark any 33 | material not subject to the license. This includes other CC- 34 | licensed material, or material used under an exception or 35 | limitation to copyright. More considerations for licensors: 36 | wiki.creativecommons.org/Considerations_for_licensors 37 | 38 | Considerations for the public: By using one of our public 39 | licenses, a licensor grants the public permission to use the 40 | licensed material under specified terms and conditions. If 41 | the licensor's permission is not necessary for any reason--for 42 | example, because of any applicable exception or limitation to 43 | copyright--then that use is not regulated by the license. Our 44 | licenses grant only permissions under copyright and certain 45 | other rights that a licensor has authority to grant. Use of 46 | the licensed material may still be restricted for other 47 | reasons, including because others have copyright or other 48 | rights in the material. A licensor may make special requests, 49 | such as asking that all changes be marked or described. 50 | Although not required by our licenses, you are encouraged to 51 | respect those requests where reasonable. More considerations 52 | for the public: 53 | wiki.creativecommons.org/Considerations_for_licensees 54 | 55 | ======================================================================= 56 | 57 | Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International 58 | Public License 59 | 60 | By exercising the Licensed Rights (defined below), You accept and agree 61 | to be bound by the terms and conditions of this Creative Commons 62 | Attribution-NonCommercial-ShareAlike 4.0 International Public License 63 | ("Public License"). To the extent this Public License may be 64 | interpreted as a contract, You are granted the Licensed Rights in 65 | consideration of Your acceptance of these terms and conditions, and the 66 | Licensor grants You such rights in consideration of benefits the 67 | Licensor receives from making the Licensed Material available under 68 | these terms and conditions. 69 | 70 | 71 | Section 1 -- Definitions. 72 | 73 | a. Adapted Material means material subject to Copyright and Similar 74 | Rights that is derived from or based upon the Licensed Material 75 | and in which the Licensed Material is translated, altered, 76 | arranged, transformed, or otherwise modified in a manner requiring 77 | permission under the Copyright and Similar Rights held by the 78 | Licensor. For purposes of this Public License, where the Licensed 79 | Material is a musical work, performance, or sound recording, 80 | Adapted Material is always produced where the Licensed Material is 81 | synched in timed relation with a moving image. 82 | 83 | b. Adapter's License means the license You apply to Your Copyright 84 | and Similar Rights in Your contributions to Adapted Material in 85 | accordance with the terms and conditions of this Public License. 86 | 87 | c. BY-NC-SA Compatible License means a license listed at 88 | creativecommons.org/compatiblelicenses, approved by Creative 89 | Commons as essentially the equivalent of this Public License. 90 | 91 | d. Copyright and Similar Rights means copyright and/or similar rights 92 | closely related to copyright including, without limitation, 93 | performance, broadcast, sound recording, and Sui Generis Database 94 | Rights, without regard to how the rights are labeled or 95 | categorized. For purposes of this Public License, the rights 96 | specified in Section 2(b)(1)-(2) are not Copyright and Similar 97 | Rights. 98 | 99 | e. Effective Technological Measures means those measures that, in the 100 | absence of proper authority, may not be circumvented under laws 101 | fulfilling obligations under Article 11 of the WIPO Copyright 102 | Treaty adopted on December 20, 1996, and/or similar international 103 | agreements. 104 | 105 | f. Exceptions and Limitations means fair use, fair dealing, and/or 106 | any other exception or limitation to Copyright and Similar Rights 107 | that applies to Your use of the Licensed Material. 108 | 109 | g. License Elements means the license attributes listed in the name 110 | of a Creative Commons Public License. The License Elements of this 111 | Public License are Attribution, NonCommercial, and ShareAlike. 112 | 113 | h. Licensed Material means the artistic or literary work, database, 114 | or other material to which the Licensor applied this Public 115 | License. 116 | 117 | i. Licensed Rights means the rights granted to You subject to the 118 | terms and conditions of this Public License, which are limited to 119 | all Copyright and Similar Rights that apply to Your use of the 120 | Licensed Material and that the Licensor has authority to license. 121 | 122 | j. Licensor means the individual(s) or entity(ies) granting rights 123 | under this Public License. 124 | 125 | k. NonCommercial means not primarily intended for or directed towards 126 | commercial advantage or monetary compensation. For purposes of 127 | this Public License, the exchange of the Licensed Material for 128 | other material subject to Copyright and Similar Rights by digital 129 | file-sharing or similar means is NonCommercial provided there is 130 | no payment of monetary compensation in connection with the 131 | exchange. 132 | 133 | l. Share means to provide material to the public by any means or 134 | process that requires permission under the Licensed Rights, such 135 | as reproduction, public display, public performance, distribution, 136 | dissemination, communication, or importation, and to make material 137 | available to the public including in ways that members of the 138 | public may access the material from a place and at a time 139 | individually chosen by them. 140 | 141 | m. Sui Generis Database Rights means rights other than copyright 142 | resulting from Directive 96/9/EC of the European Parliament and of 143 | the Council of 11 March 1996 on the legal protection of databases, 144 | as amended and/or succeeded, as well as other essentially 145 | equivalent rights anywhere in the world. 146 | 147 | n. You means the individual or entity exercising the Licensed Rights 148 | under this Public License. Your has a corresponding meaning. 149 | 150 | 151 | Section 2 -- Scope. 152 | 153 | a. License grant. 154 | 155 | 1. Subject to the terms and conditions of this Public License, 156 | the Licensor hereby grants You a worldwide, royalty-free, 157 | non-sublicensable, non-exclusive, irrevocable license to 158 | exercise the Licensed Rights in the Licensed Material to: 159 | 160 | a. reproduce and Share the Licensed Material, in whole or 161 | in part, for NonCommercial purposes only; and 162 | 163 | b. produce, reproduce, and Share Adapted Material for 164 | NonCommercial purposes only. 165 | 166 | 2. Exceptions and Limitations. For the avoidance of doubt, where 167 | Exceptions and Limitations apply to Your use, this Public 168 | License does not apply, and You do not need to comply with 169 | its terms and conditions. 170 | 171 | 3. Term. The term of this Public License is specified in Section 172 | 6(a). 173 | 174 | 4. Media and formats; technical modifications allowed. The 175 | Licensor authorizes You to exercise the Licensed Rights in 176 | all media and formats whether now known or hereafter created, 177 | and to make technical modifications necessary to do so. The 178 | Licensor waives and/or agrees not to assert any right or 179 | authority to forbid You from making technical modifications 180 | necessary to exercise the Licensed Rights, including 181 | technical modifications necessary to circumvent Effective 182 | Technological Measures. For purposes of this Public License, 183 | simply making modifications authorized by this Section 2(a) 184 | (4) never produces Adapted Material. 185 | 186 | 5. Downstream recipients. 187 | 188 | a. Offer from the Licensor -- Licensed Material. Every 189 | recipient of the Licensed Material automatically 190 | receives an offer from the Licensor to exercise the 191 | Licensed Rights under the terms and conditions of this 192 | Public License. 193 | 194 | b. Additional offer from the Licensor -- Adapted Material. 195 | Every recipient of Adapted Material from You 196 | automatically receives an offer from the Licensor to 197 | exercise the Licensed Rights in the Adapted Material 198 | under the conditions of the Adapter's License You apply. 199 | 200 | c. No downstream restrictions. You may not offer or impose 201 | any additional or different terms or conditions on, or 202 | apply any Effective Technological Measures to, the 203 | Licensed Material if doing so restricts exercise of the 204 | Licensed Rights by any recipient of the Licensed 205 | Material. 206 | 207 | 6. No endorsement. Nothing in this Public License constitutes or 208 | may be construed as permission to assert or imply that You 209 | are, or that Your use of the Licensed Material is, connected 210 | with, or sponsored, endorsed, or granted official status by, 211 | the Licensor or others designated to receive attribution as 212 | provided in Section 3(a)(1)(A)(i). 213 | 214 | b. Other rights. 215 | 216 | 1. Moral rights, such as the right of integrity, are not 217 | licensed under this Public License, nor are publicity, 218 | privacy, and/or other similar personality rights; however, to 219 | the extent possible, the Licensor waives and/or agrees not to 220 | assert any such rights held by the Licensor to the limited 221 | extent necessary to allow You to exercise the Licensed 222 | Rights, but not otherwise. 223 | 224 | 2. Patent and trademark rights are not licensed under this 225 | Public License. 226 | 227 | 3. To the extent possible, the Licensor waives any right to 228 | collect royalties from You for the exercise of the Licensed 229 | Rights, whether directly or through a collecting society 230 | under any voluntary or waivable statutory or compulsory 231 | licensing scheme. In all other cases the Licensor expressly 232 | reserves any right to collect such royalties, including when 233 | the Licensed Material is used other than for NonCommercial 234 | purposes. 235 | 236 | 237 | Section 3 -- License Conditions. 238 | 239 | Your exercise of the Licensed Rights is expressly made subject to the 240 | following conditions. 241 | 242 | a. Attribution. 243 | 244 | 1. If You Share the Licensed Material (including in modified 245 | form), You must: 246 | 247 | a. retain the following if it is supplied by the Licensor 248 | with the Licensed Material: 249 | 250 | i. identification of the creator(s) of the Licensed 251 | Material and any others designated to receive 252 | attribution, in any reasonable manner requested by 253 | the Licensor (including by pseudonym if 254 | designated); 255 | 256 | ii. a copyright notice; 257 | 258 | iii. a notice that refers to this Public License; 259 | 260 | iv. a notice that refers to the disclaimer of 261 | warranties; 262 | 263 | v. a URI or hyperlink to the Licensed Material to the 264 | extent reasonably practicable; 265 | 266 | b. indicate if You modified the Licensed Material and 267 | retain an indication of any previous modifications; and 268 | 269 | c. indicate the Licensed Material is licensed under this 270 | Public License, and include the text of, or the URI or 271 | hyperlink to, this Public License. 272 | 273 | 2. You may satisfy the conditions in Section 3(a)(1) in any 274 | reasonable manner based on the medium, means, and context in 275 | which You Share the Licensed Material. For example, it may be 276 | reasonable to satisfy the conditions by providing a URI or 277 | hyperlink to a resource that includes the required 278 | information. 279 | 3. If requested by the Licensor, You must remove any of the 280 | information required by Section 3(a)(1)(A) to the extent 281 | reasonably practicable. 282 | 283 | b. ShareAlike. 284 | 285 | In addition to the conditions in Section 3(a), if You Share 286 | Adapted Material You produce, the following conditions also apply. 287 | 288 | 1. The Adapter's License You apply must be a Creative Commons 289 | license with the same License Elements, this version or 290 | later, or a BY-NC-SA Compatible License. 291 | 292 | 2. You must include the text of, or the URI or hyperlink to, the 293 | Adapter's License You apply. You may satisfy this condition 294 | in any reasonable manner based on the medium, means, and 295 | context in which You Share Adapted Material. 296 | 297 | 3. You may not offer or impose any additional or different terms 298 | or conditions on, or apply any Effective Technological 299 | Measures to, Adapted Material that restrict exercise of the 300 | rights granted under the Adapter's License You apply. 301 | 302 | 303 | Section 4 -- Sui Generis Database Rights. 304 | 305 | Where the Licensed Rights include Sui Generis Database Rights that 306 | apply to Your use of the Licensed Material: 307 | 308 | a. for the avoidance of doubt, Section 2(a)(1) grants You the right 309 | to extract, reuse, reproduce, and Share all or a substantial 310 | portion of the contents of the database for NonCommercial purposes 311 | only; 312 | 313 | b. if You include all or a substantial portion of the database 314 | contents in a database in which You have Sui Generis Database 315 | Rights, then the database in which You have Sui Generis Database 316 | Rights (but not its individual contents) is Adapted Material, 317 | including for purposes of Section 3(b); and 318 | 319 | c. You must comply with the conditions in Section 3(a) if You Share 320 | all or a substantial portion of the contents of the database. 321 | 322 | For the avoidance of doubt, this Section 4 supplements and does not 323 | replace Your obligations under this Public License where the Licensed 324 | Rights include other Copyright and Similar Rights. 325 | 326 | 327 | Section 5 -- Disclaimer of Warranties and Limitation of Liability. 328 | 329 | a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE 330 | EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS 331 | AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF 332 | ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS, 333 | IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION, 334 | WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR 335 | PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS, 336 | ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT 337 | KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT 338 | ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU. 339 | 340 | b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE 341 | TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, 342 | NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, 343 | INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, 344 | COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR 345 | USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN 346 | ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR 347 | DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR 348 | IN PART, THIS LIMITATION MAY NOT APPLY TO YOU. 349 | 350 | c. The disclaimer of warranties and limitation of liability provided 351 | above shall be interpreted in a manner that, to the extent 352 | possible, most closely approximates an absolute disclaimer and 353 | waiver of all liability. 354 | 355 | 356 | Section 6 -- Term and Termination. 357 | 358 | a. This Public License applies for the term of the Copyright and 359 | Similar Rights licensed here. However, if You fail to comply with 360 | this Public License, then Your rights under this Public License 361 | terminate automatically. 362 | 363 | b. Where Your right to use the Licensed Material has terminated under 364 | Section 6(a), it reinstates: 365 | 366 | 1. automatically as of the date the violation is cured, provided 367 | it is cured within 30 days of Your discovery of the 368 | violation; or 369 | 370 | 2. upon express reinstatement by the Licensor. 371 | 372 | For the avoidance of doubt, this Section 6(b) does not affect any 373 | right the Licensor may have to seek remedies for Your violations 374 | of this Public License. 375 | 376 | c. For the avoidance of doubt, the Licensor may also offer the 377 | Licensed Material under separate terms or conditions or stop 378 | distributing the Licensed Material at any time; however, doing so 379 | will not terminate this Public License. 380 | 381 | d. Sections 1, 5, 6, 7, and 8 survive termination of this Public 382 | License. 383 | 384 | 385 | Section 7 -- Other Terms and Conditions. 386 | 387 | a. The Licensor shall not be bound by any additional or different 388 | terms or conditions communicated by You unless expressly agreed. 389 | 390 | b. Any arrangements, understandings, or agreements regarding the 391 | Licensed Material not stated herein are separate from and 392 | independent of the terms and conditions of this Public License. 393 | 394 | 395 | Section 8 -- Interpretation. 396 | 397 | a. For the avoidance of doubt, this Public License does not, and 398 | shall not be interpreted to, reduce, limit, restrict, or impose 399 | conditions on any use of the Licensed Material that could lawfully 400 | be made without permission under this Public License. 401 | 402 | b. To the extent possible, if any provision of this Public License is 403 | deemed unenforceable, it shall be automatically reformed to the 404 | minimum extent necessary to make it enforceable. If the provision 405 | cannot be reformed, it shall be severed from this Public License 406 | without affecting the enforceability of the remaining terms and 407 | conditions. 408 | 409 | c. No term or condition of this Public License will be waived and no 410 | failure to comply consented to unless expressly agreed to by the 411 | Licensor. 412 | 413 | d. Nothing in this Public License constitutes or may be interpreted 414 | as a limitation upon, or waiver of, any privileges and immunities 415 | that apply to the Licensor or You, including from the legal 416 | processes of any jurisdiction or authority. 417 | 418 | ======================================================================= 419 | 420 | Creative Commons is not a party to its public 421 | licenses. Notwithstanding, Creative Commons may elect to apply one of 422 | its public licenses to material it publishes and in those instances 423 | will be considered the “Licensor.” The text of the Creative Commons 424 | public licenses is dedicated to the public domain under the CC0 Public 425 | Domain Dedication. Except for the limited purpose of indicating that 426 | material is shared under a Creative Commons public license or as 427 | otherwise permitted by the Creative Commons policies published at 428 | creativecommons.org/policies, Creative Commons does not authorize the 429 | use of the trademark "Creative Commons" or any other trademark or logo 430 | of Creative Commons without its prior written consent including, 431 | without limitation, in connection with any unauthorized modifications 432 | to any of its public licenses or any other arrangements, 433 | understandings, or agreements concerning use of licensed material. For 434 | the avoidance of doubt, this paragraph does not form part of the 435 | public licenses. 436 | 437 | Creative Commons may be contacted at creativecommons.org. 438 | 439 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MTI (Meta Theme Injector) 2 |

3 | MTI 5 |

6 | 7 | Meta Theme Injector is an extension that let you customize the theme-color meta tag on websites. 8 | 9 | Most of websites still don't have the meta tag for change the color of UI of browser like address bar and the status bar on Android. 10 | Some source of theme-color meta tag [Link1](https://developers.google.com/web/updates/2015/08/using-manifest-to-set-sitewide-theme-color) [Link2](https://developers.google.com/web/updates/2014/11/Support-for-theme-color-in-Chrome-39-for-Android) 11 | 12 | MTI can be used on browsers that supports extensions like [Kiwi Browser](https://kiwibrowser.com/) 13 | 14 | Download latest version (mti.zip) -> [Releases](https://github.com/d3ward/mti/releases) 15 | 16 | ## Preview 17 | 18 | ![mtiguide](https://github.com/d3ward/mti/blob/master/src/png/mtiguide.png) 19 | 20 | ## Features 21 | 22 | - Enable/disable MTI on website 23 | - Auto detect color from website 24 | - Keep the theme-color updated on scroll 25 | - Edit default color 26 | - Input a custom color with simple sliders or just input the hex value 27 | - Import/Export 28 | (Rememeber : after any option changed you need to save ) 29 | 30 | ## Contributing 31 | 32 | If you have a suggestion feel free to share it by opening an issue 33 | 34 | ## License 35 | MTI is licensed under [(CC BY-NC-SA 4.0)](https://creativecommons.org/licenses/by-nc-sa/4.0/) 36 | 37 | This project includes [Heroicons](https://heroicons.dev/) licensed under [MTI](https://github.com/tailwindlabs/heroicons/blob/master/LICENSE) 38 | -------------------------------------------------------------------------------- /manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "manifest_version": 2, 3 | "author": "Eduard Ursu ( @d3ward )", 4 | "name": "MTI", 5 | "description": "Meta Theme Injector let you customize the theme-color meta tag", 6 | "version": "1.0.2", 7 | "browser_action": { 8 | "default_icon": "src/png/icon512.png", 9 | "default_popup": "src/popup/popup.html", 10 | "default_title": "Edit theme-color meta tag" 11 | }, 12 | "icons": { 13 | "20": "src/png/icon20.png", 14 | "48": "src/png/icon48.png", 15 | "144": "src/png/icon144.png", 16 | "256": "src/png/icon256.png", 17 | "512": "src/png/icon512.png" 18 | }, 19 | "permissions": ["tabs","storage","downloads"], 20 | "content_scripts": [{ 21 | "matches": [""], 22 | "js": ["src/js/data-storage.js","src/js/content.js"], 23 | "run_at": "document_start" 24 | }] 25 | } -------------------------------------------------------------------------------- /src/js/content.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | const rgb2hex = (rgb) => { 3 | rgb = rgb.match(/^rgba?[\s+]?\([\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?/i); 4 | return (rgb && rgb.length === 4) ? "#" + 5 | ("0" + parseInt(rgb[1], 10).toString(16)).slice(-2) + 6 | ("0" + parseInt(rgb[2], 10).toString(16)).slice(-2) + 7 | ("0" + parseInt(rgb[3], 10).toString(16)).slice(-2) : ''; 8 | } 9 | const removeDup = (arr) => { 10 | let unique_array = Array.from(new Set(arr)); 11 | return unique_array; 12 | } 13 | Array.prototype.remove = function () { 14 | var w, a = arguments, 15 | L = a.length, 16 | ax; 17 | while (L && this.length) { 18 | w = a[--L]; 19 | while ((ax = this.indexOf(w)) != -1) { 20 | this.splice(ax, 1); 21 | } 22 | } 23 | return this; 24 | } 25 | 26 | const getCFromW = (z) => { 27 | var colors = [],gvc = document.elementsFromPoint(2, 1); 28 | gvc.forEach(el => { 29 | colors.push(getComputedStyle(el).backgroundColor); 30 | colors.push(el.style.backgroundColor); 31 | }); 32 | if (colors.length > 0) { 33 | colors.push(document.body.style.backgroundColor); 34 | colors.push(getComputedStyle(document.body).backgroundColor); 35 | } 36 | colors = colors.filter(function (e) { 37 | return e 38 | }); //Remove empty ,null,undefined values 39 | colors = removeDup(colors); //Remove duplicates 40 | if (z==true) colors.remove('rgba(0, 0, 0, 0)', 'rgba(255, 255, 255, 0)', 'rgb(0, 0, 0)', 'rgb(255, 255, 255)'); //Remove white color 41 | return colors[0]; 42 | } 43 | var bgColor; 44 | const injectC = () => { 45 | if (document.querySelectorAll('meta[name="theme-color"]').length > 0) { 46 | var metaThemeColor = document.querySelector("meta[name=theme-color]"); 47 | metaThemeColor.setAttribute("content", bgColor); 48 | } else { 49 | var link = document.createElement('meta'); 50 | link.setAttribute('name', 'theme-color'); 51 | link.setAttribute('content', bgColor); 52 | document.getElementsByTagName('head')[0].appendChild(link); 53 | } 54 | } 55 | let dataStorage = new InjectedDataStorage(new DataStorage()); 56 | dataStorage.load().then(injectionData => { 57 | console.log("injectionData:" + injectionData); 58 | 59 | //Check if blacklisted 60 | if (injectionData.bl==true) return; 61 | //Get custom options 62 | const optc = injectionData.opt; 63 | const customColor = injectionData.color; 64 | var opt, defaultColor; 65 | //Get global options 66 | chrome.storage.local.get({ 67 | dfc: "#0878A5", 68 | opt: [true, true, false] 69 | }, function (items) { 70 | defaultColor = items.dfc; 71 | opt = items.opt; 72 | }); 73 | 74 | document.addEventListener("DOMContentLoaded", function () { 75 | console.log("DOM loaded:"); 76 | 77 | if (optc!=undefined && optc[0] == true) { 78 | bgColor = customColor; 79 | console.log(optc); 80 | if (optc[1]) { 81 | console.log("optc 1 is true "); 82 | bgColor = getCFromW(optc[2]); 83 | if(bgColor == undefined)bgColor=customColor; 84 | if (bgColor.indexOf("rgb") !== -1) bgColor = rgb2hex(bgColor); 85 | injectC(); 86 | console.log(bgColor); 87 | } 88 | if (optc[3]) { 89 | window.setInterval(function () { 90 | console.log(bgColor); 91 | let bgc = getCFromW(optc[2]); 92 | if(bgc!=undefined){ 93 | if (bgc.indexOf("rgb") !== -1 ) bgc = rgb2hex(bgc); 94 | if(bgColor != bgc){ 95 | bgColor=bgc; 96 | console.log(bgColor); 97 | injectC(); 98 | } 99 | } 100 | }, 600); 101 | } 102 | } else { 103 | console.log(opt); 104 | bgColor = defaultColor; 105 | console.log("Default color is enabled") 106 | if (opt[0]) { 107 | console.log("opt 0 is true "); 108 | bgColor = getCFromW(opt[1]); 109 | if(bgColor == undefined)bgColor=defaultColor; 110 | if (bgColor.indexOf("rgb") !== -1 ) bgColor = rgb2hex(bgColor); 111 | injectC(); 112 | console.log(bgColor); 113 | } 114 | if (opt[2]) { 115 | window.setInterval(function () { 116 | console.log(bgColor); 117 | let bgc = getCFromW(opt[1]); 118 | if(bgc!=undefined){ 119 | if (bgc.indexOf("rgb") !== -1 ) bgc = rgb2hex(bgc); 120 | if(bgColor != bgc){ 121 | bgColor=bgc; 122 | console.log(bgColor); 123 | injectC(); 124 | } 125 | } 126 | }, 600); 127 | } 128 | } 129 | /* 130 | //Save Data 131 | dataStorage.remove(injectionData.domain); 132 | let newData = new InjectedData(injectionData.domain, bgColor, [true, true, true, true]); 133 | dataStorage.save(newData); 134 | console.log(" Data saved ->> " + injectionData.toString()); 135 | if (!bgColor) bgColor = items.dfc; 136 | */ 137 | }); 138 | }) 139 | })() -------------------------------------------------------------------------------- /src/js/data-storage.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | class DataStorage { 3 | load(key) {return new Promise(function (resolve, reject) {chrome.storage.local.get(key, data => resolve(data[key]));});} 4 | loadAllKeys() {return new Promise(resolve => chrome.storage.local.get(null, allItems => resolve(Object.keys(allItems))));} 5 | save(key, value) { 6 | let data = {}; 7 | data[key] = value; 8 | chrome.storage.local.set(data); 9 | } 10 | remove(key) {chrome.storage.local.remove(key)} 11 | } 12 | window.DataStorage = DataStorage; 13 | class InjectedData { 14 | constructor(domain,color,opt,bl) { 15 | this.color = color ? color : "default"; 16 | this.domain = domain; 17 | this.opt= (opt)? opt: [false,false,false,false]; 18 | this.bl = bl; 19 | 20 | } 21 | serialize() { 22 | return { 23 | color: this.color, 24 | domain: this.domain, 25 | opt: this.opt, 26 | bl: this.bl 27 | } 28 | } 29 | static deserialize(key, serializedData) { 30 | return new InjectedData(key, serializedData.color,serializedData.opt ,serializedData.bl); 31 | } 32 | } 33 | window.InjectedData = InjectedData; 34 | function wildcardMatch(find, source) { 35 | find = find.replace(/[\-\[\]\/\{\}\(\)\+\.\\\^\$\|]/g, "\\$&"); 36 | find = find.replace(/\*/g, ".*"); 37 | find = find.replace(/\?/g, "."); 38 | var regEx = new RegExp(find, "i"); 39 | return regEx.test(source); 40 | } 41 | class InjectedDataStorage { 42 | constructor(dataStorage) {this.dataStorage = dataStorage;} 43 | load() { 44 | let hostName = InjectedDataStorage.getCurrentDomain(); 45 | return this.dataStorage.loadAllKeys().then(allKeys => { 46 | for (let key of allKeys) { 47 | if (!wildcardMatch(key, hostName)) continue; 48 | return this.dataStorage.load(key).then(value => InjectedData.deserialize(key, value)); 49 | } 50 | return false; 51 | }) 52 | } 53 | remove(key) {this.dataStorage.remove(key);} 54 | save(injectedData) {this.dataStorage.save(injectedData.domain, injectedData.serialize())} 55 | static getCurrentDomain() { 56 | var url = window.location.href; 57 | if (window.tab && window.tab.url) url = tab.url; 58 | console.log(url); 59 | if(url.match(/[^\/]+\/\/[^\/]+/) != undefined) 60 | return url.match(/[^\/]+\/\/[^\/]+/)[0]; 61 | } 62 | } 63 | window.InjectedDataStorage = InjectedDataStorage; 64 | })() -------------------------------------------------------------------------------- /src/png/icon144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d3ward/mti/2498e0bb90d648586585aa7f97413a3e94048be0/src/png/icon144.png -------------------------------------------------------------------------------- /src/png/icon20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d3ward/mti/2498e0bb90d648586585aa7f97413a3e94048be0/src/png/icon20.png -------------------------------------------------------------------------------- /src/png/icon256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d3ward/mti/2498e0bb90d648586585aa7f97413a3e94048be0/src/png/icon256.png -------------------------------------------------------------------------------- /src/png/icon48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d3ward/mti/2498e0bb90d648586585aa7f97413a3e94048be0/src/png/icon48.png -------------------------------------------------------------------------------- /src/png/icon512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d3ward/mti/2498e0bb90d648586585aa7f97413a3e94048be0/src/png/icon512.png -------------------------------------------------------------------------------- /src/png/mtiguide.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d3ward/mti/2498e0bb90d648586585aa7f97413a3e94048be0/src/png/mtiguide.png -------------------------------------------------------------------------------- /src/popup/popup.css: -------------------------------------------------------------------------------- 1 | html, 2 | [data-theme='light'] { 3 | --black: #000; 4 | --white: #fff; 5 | --green: #2ECC40; 6 | --blue: #0074D8; 7 | --red: #FF4132; 8 | --orange: #FF851A; 9 | --yellow: #ffcd36; 10 | --primary: var(--blue); 11 | --accent: #E3F2FD; 12 | --active:#ECEFF1; 13 | --focus: 2px rgba(39, 94, 254, .3); 14 | --hover:#ECF4FD; 15 | --txt: #14191f; 16 | --txt-r: var(--white); 17 | --bg: #fff; 18 | --bg2: #F6FAFD; 19 | --bg3: #edf0f2; 20 | --brd: #E5E9ED; 21 | --brd2: #a8afb6; 22 | --bg-nav: var(--bg); 23 | --bg-nav-hover: var(--hover); 24 | --bb-nav: var(--primary); 25 | --bg-input: #fff; 26 | --brd-input: #B6BEC5; 27 | --bg-disabled: #EEF2F5; 28 | --bg-btn: var(--primary); 29 | --bg-btn-hover: inset 0 0 100px 100px #ffffff20; 30 | --txt-btn: var(--white); 31 | --brd-btn: var(--primary); 32 | --bg-card: var(--bg); 33 | --bg-details: var(--bg2); 34 | --bg-details-open: var(--primary); 35 | --txt-details-open: var(--txt-r); 36 | --bg-aside: transparent; 37 | --shadow-aside: none; 38 | --bg-tabs: var(--bg); 39 | --brd-tabs-l: var(--primary); 40 | --fake-brd-table: inset 0 0px 0px 1px rgb(0 0 0 / 16%); 41 | --bg-table-hover: var(--bg3); 42 | --brd-table: var(--bg3); 43 | --shadow: rgba(99, 99, 99, 0.2) 0px 2px 8px 0px; 44 | --radius: .4rem; 45 | } 46 | 47 | [data-theme="dark"] { 48 | --black: #060609; 49 | --white: #f2f4f7; 50 | --blue: #4dacff; 51 | --green: #67e5a8; 52 | --red: #ff564d; 53 | --orange: #ff9f4d; 54 | --yellow: #ffd24d; 55 | --txt: #f2f4f7; 56 | --txt-r: #14191f; 57 | --bg3: #2F3C53; 58 | --bg2: #263349; 59 | --bg: #1E2A41; 60 | --bg-nav: var(--bg); 61 | --bg-nav-hover: var(--bg2); 62 | --bg-input: var(--bg); 63 | --brd-input: #576d97; 64 | --bg-disabled: var(--bg); 65 | --bg-btn: var(--primary); 66 | --bg-btn-hover: inset 0 0 100px 100px #00000033; 67 | --brd-btn: var(--primary); 68 | --txt-btn: var(--black); 69 | --bg-card: var(--bg2); 70 | --shadow: none; 71 | } 72 | 73 | [data-theme="light"] .light-icon, 74 | [data-theme="dark"] .dark-icon { 75 | display: block !important; 76 | } 77 | 78 | .theme-icon { 79 | display: none; 80 | } 81 | 82 | .theme-icon>svg { 83 | fill: var(--txt); 84 | } 85 | 86 | /* ---------------- Basic resets and improvements --------------- */ 87 | *, 88 | *:after, 89 | *:before { 90 | box-sizing: border-box; 91 | border-spacing: 0; 92 | } 93 | 94 | html { 95 | font-family: -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", sans-serif; 96 | font-size: 13pt; 97 | scroll-behavior: smooth; 98 | color: var(--txt); 99 | background: var(--bg); 100 | } 101 | 102 | body, html { 103 | margin: 0; 104 | padding: 0; 105 | } 106 | 107 | hr { 108 | border: 0; 109 | border-top: 2px solid var(--brd); 110 | } 111 | 112 | /* ------------------ Heading ----------------- */ 113 | h1, h2, h3, h4, h5, h6 { 114 | margin-top: 1.5rem; 115 | } 116 | 117 | h1 { 118 | font-size: 2.6em; 119 | } 120 | 121 | h2,.h2 { 122 | font-size: 2em!important; 123 | } 124 | 125 | h3 { 126 | font-size: 1.7em; 127 | } 128 | 129 | h4 { 130 | font-size: 1.5em; 131 | } 132 | 133 | h5 { 134 | font-size: 1.2em; 135 | } 136 | 137 | h6 { 138 | font-size: 1em; 139 | } 140 | 141 | main { 142 | margin: auto; 143 | max-width: 450px; 144 | min-width: 300px; 145 | width: 100%; 146 | padding: 1rem; 147 | padding-top: 4rem; 148 | overflow-x: hidden; 149 | } 150 | @media (max-width: 400px) { 151 | main{ 152 | min-width: none; 153 | } 154 | } 155 | ._2-col { 156 | display: grid; 157 | grid-template-columns: 1fr 1fr; 158 | gap: .5rem; 159 | } 160 | /* ------------------ Footer ------------------ */ 161 | footer { 162 | text-align: center; 163 | padding: 1rem 0; 164 | } 165 | /* ------------------ Navbar ------------------ */ 166 | header { 167 | width: 100%; 168 | z-index: 1; 169 | padding: .5rem; 170 | } 171 | 172 | header.fixed { 173 | position: fixed; 174 | top: 0; 175 | } 176 | 177 | nav { 178 | position: relative; 179 | display: flex; 180 | justify-content: space-between; 181 | align-items: stretch; 182 | background-color: var(--bg-nav); 183 | width: 100%; 184 | max-width: 60rem; 185 | margin: auto; 186 | z-index: 1; 187 | border-radius: var(--radius); 188 | border-bottom: 1px solid var(--bb-nav); 189 | padding: .4rem; 190 | box-shadow: var(--shadow); 191 | } 192 | 193 | nav * { 194 | margin: 0; 195 | padding: 0; 196 | } 197 | 198 | nav>ul { 199 | width: auto; 200 | list-style: none; 201 | display: flex; 202 | flex-flow: nowrap row; 203 | align-items: center; 204 | justify-content: flex-end; 205 | gap: .5rem; 206 | overflow: unset; 207 | } 208 | 209 | nav>div { 210 | display: flex; 211 | flex: auto; 212 | align-items: center; 213 | justify-content: space-between; 214 | } 215 | 216 | nav ul li, 217 | nav li>* { 218 | display: flex; 219 | align-items: center; 220 | text-align: center; 221 | } 222 | 223 | nav li>* { 224 | color: var(--txt); 225 | text-decoration: none; 226 | padding: .4rem; 227 | border-radius: var(--radius); 228 | transition: background .4s linear; 229 | } 230 | 231 | nav li>a:hover, 232 | nav li>div:hover { 233 | color: var(--primary); 234 | background: var(--bg-nav-hover); 235 | } 236 | 237 | nav svg,nav img { 238 | display: block; 239 | height: 1.4rem; 240 | width: 1.4rem; 241 | fill: var(--txt); 242 | margin: 0 auto; 243 | max-height: 1.7rem; 244 | } 245 | 246 | nav li>a:hover>svg, 247 | nav li>div:hover>svg { 248 | fill: var(--primary); 249 | } 250 | 251 | nav>div>a>svg { 252 | max-height: 1.7rem; 253 | } 254 | 255 | nav>div>a { 256 | display: flex; 257 | align-items: center; 258 | font-size: 1.7rem; 259 | } 260 | 261 | /* ------------------- Links ------------------ */ 262 | a { 263 | color: var(--primary); 264 | text-decoration: none; 265 | cursor: pointer; 266 | } 267 | a:not([class*=btn]) { 268 | border-bottom: 2px solid transparent; 269 | } 270 | a:not([class*=btn]):hover { 271 | border-bottom: 2px solid currentColor; 272 | } 273 | ._overflowhidden { 274 | overflow: hidden !important; 275 | } 276 | /* ------------------- Modal ------------------ */ 277 | .modal { 278 | display: flex; 279 | position: fixed; 280 | width: 100%; 281 | height: 100%; 282 | opacity: 0; 283 | visibility: hidden; 284 | background: rgba(0, 0, 0, 0.4); 285 | -webkit-backdrop-filter: blur(4px); 286 | backdrop-filter: blur(4px); 287 | transition: all 0.3s ease-in; 288 | z-index: -1; 289 | } 290 | .modal > div { 291 | border-radius: 0.3em; 292 | margin: auto; 293 | padding: 0.8em; 294 | overflow: hidden; 295 | width: 85vw; 296 | max-width: 300px; 297 | opacity: 0; 298 | background: var(--bg); 299 | transform: scale(0.9); 300 | transition: all 0.3s ease-out; 301 | } 302 | .modal > div > div { 303 | max-width: 500px; 304 | } 305 | .modal > div > footer { 306 | text-align: end; 307 | padding: 0; 308 | } 309 | .modal > div > header { 310 | display: flex; 311 | align-items: center; 312 | justify-content: space-between; 313 | } 314 | .modal > div > header > * { 315 | margin: 0; 316 | } 317 | .modal._show-modal { 318 | visibility: visible; 319 | opacity: 1; 320 | z-index: 200; 321 | } 322 | .modal._show-modal > div { 323 | opacity: 1; 324 | transform: scale(1); 325 | transition: all 0.2s ease-in; 326 | } 327 | 328 | 329 | /* ------------------ Buttons ----------------- */ 330 | button, 331 | [class^=btn] { 332 | display: inline-flex; 333 | align-items: center; 334 | text-align: center; 335 | justify-content: center; 336 | border: 0px; 337 | color: var(--txt-btn); 338 | background-color: var(--bg-btn); 339 | outline: none; 340 | padding: 0.6rem; 341 | font-size: inherit; 342 | cursor: pointer; 343 | border-radius: var(--radius); 344 | margin: 0.5rem; 345 | height: 2.6rem; 346 | min-width: 100px; 347 | transition: all 0.2s ease-in-out; 348 | -webkit-tap-highlight-color: transparent; 349 | } 350 | button:focus, 351 | [class^=btn]:focus { 352 | outline: none; 353 | } 354 | button.mw-auto, 355 | [class^=btn].mw-auto { 356 | min-width: unset; 357 | } 358 | button[disabled], 359 | [class^=btn][disabled] { 360 | opacity: 0.5; 361 | pointer-events: none; 362 | cursor: not-allowed; 363 | } 364 | button:not([disabled]):hover, 365 | [class^=btn]:not([disabled]):hover { 366 | box-shadow: var(--bg-btn-hover); 367 | } 368 | button.ghost, 369 | [class^=btn].ghost { 370 | background: transparent; 371 | color: var(--txt); 372 | border: 2px solid var(--bg-btn); 373 | } 374 | button.ghost:hover, 375 | [class^=btn].ghost:hover { 376 | background: var(--bg-btn); 377 | color: var(--txt-btn) !important; 378 | box-shadow: none; 379 | } 380 | button > svg, 381 | [class^=btn] > svg,._icon { 382 | height: 1.3rem; 383 | width: 1.3rem; 384 | fill: currentColor; 385 | max-height: 1.7rem; 386 | } 387 | 388 | .btn-transparent { 389 | --bg-btn: transparent; 390 | --txt-btn: var(--txt-r); 391 | } 392 | 393 | .btn-cl2 { 394 | --bg-btn: var(--txt-r); 395 | --txt-btn: var(--txt); 396 | } 397 | 398 | .btn-bg2 { 399 | --bg-btn: var(--bg2); 400 | --txt-btn: var(--txt); 401 | } 402 | 403 | .btn-black { 404 | --bg-btn: var(--black); 405 | --txt-btn: var(--white); 406 | } 407 | 408 | .btn-white { 409 | --bg-btn: var(--white); 410 | --txt-btn: var(--black); 411 | } 412 | 413 | .btn-blue { 414 | --bg-btn: var(--blue); 415 | --txt-btn: var(--txt-r); 416 | } 417 | 418 | .btn-red { 419 | --bg-btn: var(--red); 420 | --txt-btn: var(--txt); 421 | } 422 | 423 | .btn-green { 424 | --bg-btn: var(--green); 425 | --txt-btn: var(--black); 426 | } 427 | 428 | .btn-orange { 429 | --bg-btn: var(--orange); 430 | --txt-btn: var(--black); 431 | } 432 | 433 | .btn-yellow { 434 | --bg-btn: var(--yellow); 435 | --txt-btn: var(--black); 436 | } 437 | 438 | 439 | /* ----------- Grid columns and row ----------- */ 440 | .grid { 441 | flex-wrap: wrap; 442 | } 443 | 444 | .row, .grid { 445 | display: flex; 446 | align-items: stretch; 447 | margin: 1rem 0 0 0; 448 | } 449 | 450 | .row > [class*="col"], .row > div, .grid > [class*="col"], .grid > div { 451 | flex: 0 0 auto; 452 | flex-shrink: 0; 453 | width: 100%; 454 | max-width: 100%; 455 | padding: .5rem; 456 | } 457 | 458 | .row > [class*="col"] > *, .row > div > *, .grid > [class*="col"] > *, .grid > div > * { 459 | margin: 0; 460 | } 461 | 462 | .row .col, .row > div, .grid .col, .grid > div { 463 | flex: 1 1 100%; 464 | } 465 | 466 | @media (max-width: 40em) { 467 | .row:not(.keep-width) > [class*="col"], .row:not(.keep-width) > div, .grid:not(.keep-width) > [class*="col"], .grid:not(.keep-width) > div { 468 | width: auto; 469 | } 470 | } 471 | 472 | /* --------------- Toast Message -------------- */ 473 | .alert-item { 474 | transition: all 0.3s; 475 | max-width: 300px; 476 | padding: 0.8rem; 477 | width: 90vw; 478 | margin-bottom: 0.3rem; 479 | display: flex; 480 | background: var(--primary); 481 | border-radius: var(--radius); 482 | box-shadow: var(--shadow); 483 | -webkit-animation: fade-in 0.3s; 484 | animation: fade-in 0.3s; 485 | -webkit-animation-timing-function: cubic-bezier(0.6, 0.04, 0.98, 0.34); 486 | animation-timing-function: cubic-bezier(0.6, 0.04, 0.98, 0.34); 487 | } 488 | .alert-item.animate-out { 489 | -webkit-animation: fade-out 0.3s; 490 | animation: fade-out 0.3s; 491 | -webkit-animation-timing-function: cubic-bezier(0.6, 0.04, 0.98, 0.34); 492 | animation-timing-function: cubic-bezier(0.6, 0.04, 0.98, 0.34); 493 | } 494 | .alert-item.success { 495 | background: var(--green); 496 | } 497 | .alert-item.error { 498 | background: var(--red); 499 | } 500 | .alert-item.warn { 501 | background: var(--yellow); 502 | } 503 | .alert-item.info { 504 | background: var(--blue); 505 | } 506 | 507 | .alert-container { 508 | position: fixed; 509 | padding: 0.3rem; 510 | display: flex; 511 | align-items: center; 512 | flex-direction: column; 513 | z-index: 9999; 514 | } 515 | .alert-container._top { 516 | flex-direction: column-reverse; 517 | } 518 | .alert-container._bottom { 519 | bottom: 0; 520 | } 521 | .alert-container._left { 522 | left: 0; 523 | } 524 | .alert-container._right { 525 | right: 0; 526 | } 527 | .alert-container._center { 528 | left: 50%; 529 | transform: translateX(-50%); 530 | } 531 | 532 | @-webkit-keyframes fade-out { 533 | from { 534 | opacity: 1; 535 | transform: scaleY(1); 536 | } 537 | to { 538 | opacity: 0; 539 | transform: scaleY(0); 540 | } 541 | } 542 | 543 | @keyframes fade-out { 544 | from { 545 | opacity: 1; 546 | transform: scaleY(1); 547 | } 548 | to { 549 | opacity: 0; 550 | transform: scaleY(0); 551 | } 552 | } 553 | @-webkit-keyframes fade-in { 554 | from { 555 | opacity: 0; 556 | transform: scaleY(0); 557 | } 558 | to { 559 | opacity: 1; 560 | transform: scaleY(1); 561 | } 562 | } 563 | @keyframes fade-in { 564 | from { 565 | opacity: 0; 566 | transform: scaleY(0); 567 | } 568 | to { 569 | opacity: 1; 570 | transform: scaleY(1); 571 | } 572 | } 573 | /* ----------------- Utilities ---------------- */ 574 | 575 | ._list-box{ 576 | list-style: none; 577 | padding: 0; 578 | display: flex; 579 | flex-direction: column; 580 | gap: .5rem; 581 | } 582 | ._list-box>li{ 583 | margin: 0; 584 | } 585 | 586 | .slider { 587 | -webkit-appearance: none; 588 | appearance: none; 589 | width: 100%; 590 | height: 30px; 591 | outline: none; 592 | margin: 0 auto; 593 | } 594 | 595 | .slider::-webkit-slider-thumb { 596 | -webkit-appearance: none; 597 | appearance: none; 598 | width: 28px; 599 | height: 28px; 600 | border-radius: 30px; 601 | border: 2px var(--white) solid; 602 | background: var(--white); 603 | box-shadow: var(--shadow); 604 | cursor: pointer; 605 | } 606 | 607 | .satcolor { 608 | background-color: transparent; 609 | } 610 | 611 | .hue, 612 | .sat, 613 | .light { 614 | box-sizing: border-box; 615 | border: 2px var(--txt) solid; 616 | box-shadow: var(--shadow); 617 | border-radius: 20px; 618 | } 619 | 620 | .hue { 621 | background-image: linear-gradient(to right, red, orange, yellow, green, blue, indigo, violet); 622 | } 623 | 624 | .sat { 625 | background-image: linear-gradient(to right, #494949 0%, transparent 100%), linear-gradient(to right, #fff 0%, transparent 0%); 626 | } 627 | 628 | .light { 629 | background-image: linear-gradient(to right, #000 0%, transparent 100%), linear-gradient(to right, #fff 0%, transparent 100%); 630 | } 631 | 632 | /* ------------------- Input ------------------ */ 633 | 634 | input[type=color] { 635 | -webkit-appearance: none; 636 | border: none; 637 | border-radius: var(--radius); 638 | width: 32px; 639 | height: 32px; 640 | } 641 | 642 | input[type=color]::-webkit-color-swatch-wrapper { 643 | padding: 0; 644 | } 645 | 646 | input[type=color]::-webkit-color-swatch { 647 | border: none; 648 | border-radius: var(--radius); 649 | } 650 | 651 | textarea, 652 | input:not([type=color]):not([type=range]):not([type=radio]):not([type=checkbox]), 653 | select { 654 | color: var(--txt); 655 | background: var(--bg-input); 656 | padding: 0.6rem; 657 | border-radius: var(--radius); 658 | width: 100%; 659 | border: 2px solid var(--brd-input); 660 | outline: none; 661 | height: 2.5rem; 662 | transition: background 0.3s, border-color 0.3s, box-shadow 0.2s; 663 | } 664 | 665 | fieldset { 666 | margin-top: 1rem; 667 | border-radius: var(--radius); 668 | border: 2px solid var(--brd-input); 669 | } 670 | 671 | input:disabled, textarea:disabled { 672 | opacity: 0.5 !important; 673 | background: var(--bg-disabled) !important; 674 | } 675 | 676 | textarea:focus, 677 | input:not([type=checkbox]):not([type=radio]):not([type=color]):not([type=range]):focus, 678 | select:focus { 679 | box-shadow: 0 0 0 var(--focus); 680 | } 681 | 682 | textarea:hover, 683 | input:not([disabled]):not([type=checkbox]):not([type=radio]):not([type=color]):not([type=range]):hover, 684 | select:hover { 685 | border: 2px solid var(--primary); 686 | } 687 | 688 | @supports (-webkit-appearance: none) or (-moz-appearance: none) { 689 | input[type=checkbox], 690 | input[type=radio] { 691 | -webkit-appearance: none; 692 | -moz-appearance: none; 693 | height: 21px; 694 | outline: none; 695 | display: inline-block; 696 | vertical-align: middle; 697 | position: relative; 698 | margin: 0; 699 | cursor: pointer; 700 | border: 2px solid var(--brd-input); 701 | background: var(--bg-input); 702 | transition: background 0.3s, border-color 0.3s, box-shadow 0.2s; 703 | } 704 | input[type=checkbox]:after, 705 | input[type=radio]:after { 706 | content: ""; 707 | display: block; 708 | left: 0; 709 | top: 0; 710 | position: absolute; 711 | transition: transform 0.3s ease, opacity 0.2s; 712 | } 713 | input[type=checkbox]:checked, 714 | input[type=radio]:checked { 715 | background: var(--primary); 716 | border-color: var(--primary); 717 | } 718 | input[type=checkbox]:disabled, 719 | input[type=radio]:disabled { 720 | background: var(--bg-disabled); 721 | cursor: not-allowed; 722 | opacity: 0.9; 723 | } 724 | input[type=checkbox]:disabled + label, 725 | input[type=radio]:disabled + label { 726 | cursor: not-allowed; 727 | } 728 | input[type=checkbox]:hover:not(:checked):not(:disabled), 729 | input[type=radio]:hover:not(:checked):not(:disabled) { 730 | border-color: var(--primary); 731 | } 732 | input[type=checkbox]:focus, 733 | input[type=radio]:focus { 734 | box-shadow: 0 0 0 var(--focus); 735 | } 736 | input[type=checkbox]:not(.toggle), 737 | input[type=radio]:not(.toggle) { 738 | width: 21px; 739 | } 740 | input[type=checkbox]:not(.toggle):after, 741 | input[type=radio]:not(.toggle):after { 742 | opacity: var(--o, 0); 743 | } 744 | input[type=checkbox]:not(.toggle):checked, 745 | input[type=radio]:not(.toggle):checked { 746 | --o: 1; 747 | } 748 | input[type=checkbox] + label, 749 | input[type=radio] + label { 750 | font-size: 14px; 751 | line-height: 21px; 752 | display: inline-block; 753 | vertical-align: top; 754 | cursor: pointer; 755 | margin-left: 4px; 756 | } 757 | 758 | input[type=checkbox]:not(.toggle) { 759 | border-radius: 7px; 760 | } 761 | input[type=checkbox]:not(.toggle):after { 762 | width: 5px; 763 | height: 9px; 764 | border: 2px solid var(--bg-input); 765 | border-top: 0; 766 | border-left: 0; 767 | left: 6px; 768 | top: 3px; 769 | transform: rotate(var(--r, 20deg)); 770 | } 771 | input[type=checkbox]:not(.toggle):checked { 772 | --r: 43deg; 773 | } 774 | input[type=checkbox].toggle { 775 | width: 38px; 776 | border-radius: 11px; 777 | } 778 | input[type=checkbox].toggle:after { 779 | left: 1px; 780 | top: 1px; 781 | border-radius: 50%; 782 | width: 15px; 783 | height: 15px; 784 | background: var(--b-brd, var(--brd-input)); 785 | transform: translateX(var(--x, 0)); 786 | } 787 | input[type=checkbox].toggle:checked { 788 | --x: 17px; 789 | --b-brd: var(--bg-input); 790 | } 791 | input[type=checkbox].toggle:disabled:not(:checked):after { 792 | opacity: 0.6; 793 | } 794 | 795 | input[type=radio] { 796 | border-radius: 50%; 797 | } 798 | input[type=radio]:after { 799 | width: 17px; 800 | height: 17px; 801 | border-radius: 50%; 802 | background: var(--bg-input); 803 | opacity: 0; 804 | transform: scale(var(--s, 0.7)); 805 | } 806 | input[type=radio]:checked { 807 | --s: .5; 808 | } 809 | } 810 | 811 | [class^=with-icon] { 812 | position: relative; 813 | max-width: 150px; 814 | margin: auto!important; 815 | } 816 | 817 | [class^=with-icon] > span { 818 | position: absolute; 819 | top: 50%; 820 | transform: translateY(-50%); 821 | } 822 | 823 | .with-icon-left > span { 824 | left: .4rem; 825 | } 826 | 827 | .with-icon-right > span { 828 | right: .4rem; 829 | } 830 | 831 | .with-icon-left > input { 832 | padding-left: 3rem !important; 833 | } 834 | 835 | .with-icon-right > input { 836 | pointer-events: none; 837 | padding-right: 3rem !important; 838 | } 839 | 840 | .clfrt { 841 | display: inline-block; 842 | position: relative; 843 | border-radius: 10px; 844 | border: 3px solid black; 845 | width: 30px; 846 | height: 30px; 847 | background: transparent; 848 | margin-bottom: 0.8rem; 849 | } 850 | ._m-0{ 851 | margin: 0; 852 | } 853 | 854 | /* ------------------- Card ------------------- */ 855 | .card { 856 | display: flex; 857 | flex-wrap: wrap; 858 | gap: 1rem; 859 | height: 100%; 860 | padding: 1rem; 861 | background: var(--bg-card); 862 | border-radius: var(--radius); 863 | box-shadow: var(--shadow); 864 | } 865 | .card > * { 866 | width: 100%; 867 | margin: 0; 868 | } -------------------------------------------------------------------------------- /src/popup/popup.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | MTI Popup 5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 |
13 | 14 | 42 | 43 | 58 | 59 |
60 | 105 |
106 |
107 |
108 |
109 |
110 |
Reset to current domain
111 |
112 |
113 | 114 |
115 |
116 |
117 |

Global Options

118 |
119 |
120 |
121 | 122 | 123 |
124 |
    125 |
  • 126 | 127 | 128 |
  • 129 |
  • 130 | 131 | 132 |
  • 133 |
  • 134 | 135 | 136 |
  • 137 |
138 |
139 | 140 |
141 | 142 | 143 |
144 |
145 |
146 | 147 | 148 |
149 |
    150 |
  • 151 | 152 | 153 |
  • 154 |
  • 155 | 156 | 157 |
  • 158 |
  • 159 | 160 | 161 |
  • 162 |
163 |
164 |
165 |

Advanced

166 |
167 |
168 |
169 | 175 | 182 | 188 | 194 |
195 | 196 | 197 |
198 |
199 |
200 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | -------------------------------------------------------------------------------- /src/popup/popup.js: -------------------------------------------------------------------------------- 1 | function alert(options) { 2 | var t = this; 3 | if (!options) options = []; 4 | t.count = 0; 5 | t.timeout = (options.timeout) ? options.timeout : 3000; 6 | t.autoClose = (options.autoClose) ? options.autoClose : true; 7 | const close = ''; 8 | t.container = document.querySelector("#nt1"); 9 | t.close = ($el) => { 10 | $el.classList.add("animate-out"); 11 | setTimeout(() => { 12 | $el.remove(); 13 | t.count--; 14 | }, 300); 15 | } 16 | t.setCloseOnClick = ($el) => { 17 | $el.addEventListener("click", function () { 18 | t.close($el); 19 | }); 20 | } 21 | t.setAutocloseTimeout = ($el, timeout) => { 22 | setTimeout(() => { 23 | t.close($el); 24 | }, timeout); 25 | } 26 | t.createItem = (message, type) => { 27 | var $item = document.createElement("div"); 28 | $item.classList.add("alert-item"); 29 | $item.classList.add(type); 30 | $item.innerHTML = "" + message + "" + close; 31 | t.count++; 32 | return $item; 33 | } 34 | 35 | t.error = (txt) => { 36 | t.showA(t.createItem(txt, "error")); 37 | } 38 | t.warn = (txt) => { 39 | t.showA(t.createItem(txt, "warn")); 40 | } 41 | t.info = (txt) => { 42 | var l = t.createItem(txt, "info"); 43 | t.showA(l); 44 | } 45 | t.success = (txt) => { 46 | var l = t.createItem(txt, "success"); 47 | t.showA(l); 48 | } 49 | t.show = (txt) => { 50 | var l = t.createItem(txt, ""); 51 | t.showA(l); 52 | } 53 | t.showA = (l) => { 54 | if (t.autoClose == true) 55 | t.setAutocloseTimeout(l, t.timeout); 56 | t.setCloseOnClick(l); 57 | t.container.append(l); 58 | } 59 | 60 | } 61 | 62 | function modal(id) { 63 | var t = this; 64 | t.m = document.querySelector((id) ? id : '.modal'); 65 | if (t.m) { 66 | t.bdy = document.body.classList; 67 | t.targets = document.querySelectorAll('[data-toggle="' + t.m.id + '"]'); 68 | t.closebtns = t.m.querySelectorAll('.close-modal'); 69 | } 70 | t.show = function () { 71 | t.bdy.add('_overflowhidden'); 72 | t.m.classList.add('_show-modal'); 73 | } 74 | t.hide = function () { 75 | t.m.classList.remove('_show-modal'); 76 | t.bdy.remove('_overflowhidden'); 77 | } 78 | t.listeners = function () { 79 | t.targets.forEach(el => { 80 | el.addEventListener('click', function (e) { 81 | t.show(); 82 | }); 83 | }); 84 | t.closebtns.forEach(function (item) { 85 | item.addEventListener('click', function (e) { 86 | t.hide(); 87 | }); 88 | }); 89 | } 90 | if (t.m) 91 | t.listeners(); 92 | } 93 | 94 | function themeManager() { 95 | const t = this; 96 | t.toggles = document.getElementsByClassName("theme-toggle"); 97 | t.activeTheme = "light"; 98 | t.setTheme = (theme) => { 99 | t.activeTheme = theme; 100 | document.documentElement.setAttribute('data-theme', theme) 101 | localStorage.setItem('theme', theme); 102 | } 103 | t.dark = () => { 104 | t.setTheme("dark"); 105 | } 106 | t.light = () => { 107 | t.setTheme("light"); 108 | } 109 | if (window.CSS && CSS.supports("color", "var(--bg)") && t.toggles) { 110 | var storedTheme = localStorage.getItem('theme') || (window.matchMedia("(prefers-color-scheme: dark)").matches ? 111 | "dark" : "light"); 112 | if (storedTheme) 113 | document.documentElement.setAttribute('data-theme', storedTheme) 114 | for (var i = 0; i < t.toggles.length; i++) { 115 | t.toggles[i].onclick = function () { 116 | if (document.documentElement.getAttribute("data-theme") === "light") t.dark(); 117 | else t.light(); 118 | }; 119 | } 120 | } 121 | } 122 | 123 | function gotop() { 124 | var t = this; 125 | t.gt = document.getElementById('gt-link'); 126 | t.scrollToTop = function () { 127 | window.scroll({ 128 | top: 0, 129 | left: 0, 130 | behavior: 'smooth' 131 | }); 132 | } 133 | t.listeners = function () { 134 | window.addEventListener("scroll", () => { 135 | let y = window.scrollY; 136 | if (y > 0) { 137 | t.gt.classList.remove("hidden"); 138 | } else { 139 | t.gt.classList.add("hidden"); 140 | } 141 | }); 142 | t.gt.onclick = function (e) { 143 | e.preventDefault(); 144 | if (document.documentElement.scrollTop || document.body.scrollTop > 0) { 145 | t.scrollToTop(); 146 | } 147 | } 148 | } 149 | if (t.gt) { 150 | t.listeners(); 151 | } 152 | } 153 | 154 | let dmn_inp = document.getElementById("dmn"); 155 | let chk_st = document.getElementById("st_bl"); 156 | let opt0c = document.getElementById("opt0c"); 157 | let opt1c = document.getElementById("opt1c"); 158 | let opt2c = document.getElementById("opt2c"); 159 | let opt0 = document.getElementById("opt0"); 160 | let opt1 = document.getElementById("opt1"); 161 | let opt2 = document.getElementById("opt2"); 162 | let metaThemeColor = document.querySelector("meta[name=theme-color]"); 163 | let dataStorage = new InjectedDataStorage(new DataStorage()); 164 | let currentInjectionData; 165 | let hue = 0, 166 | sat = 0, 167 | light = 0; 168 | var defaultColor, hexValue, customChanged = false, 169 | currentisdefault = false; 170 | const hueInput = document.getElementById("hue"); 171 | const satInput = document.getElementById("sat"); 172 | const lightInput = document.getElementById("light"); 173 | const swatch = document.querySelector('.swatch'); 174 | const hexInput = document.getElementById("hex_in"); 175 | const hexInput_g = document.getElementById("hex_global"); 176 | const hexInput_c = document.getElementById("hex_custom"); 177 | const hex_gcl = document.getElementById("hex_global_cl"); 178 | const hex_ccl = document.getElementById("hex_custom_cl"); 179 | let lrtStatus = 0; 180 | const hslToHex = (h, s, l) => { 181 | h /= 360, s /= 100, l /= 100; 182 | let r, g, b; 183 | if (s === 0) { 184 | r = g = b = l; // achromatic 185 | } else { 186 | const hue2rgb = (p, q, t) => { 187 | if (t < 0) t += 1; 188 | if (t > 1) t -= 1; 189 | if (t < 1 / 6) return p + (q - p) * 6 * t; 190 | if (t < 1 / 2) return q; 191 | if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6; 192 | return p; 193 | }; 194 | const q = l < 0.5 ? l * (1 + s) : l + s - l * s; 195 | const p = 2 * l - q; 196 | r = hue2rgb(p, q, h + 1 / 3); 197 | g = hue2rgb(p, q, h); 198 | b = hue2rgb(p, q, h - 1 / 3); 199 | } 200 | const toHex = x => { 201 | const hex = Math.round(x * 255).toString(16); 202 | return hex.length === 1 ? '0' + hex : hex; 203 | }; 204 | return `#${toHex(r)}${toHex(g)}${toHex(b)}`; 205 | } 206 | const hexToHsl = (hex) => { 207 | hexInput.value = hex; 208 | var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex); 209 | var r = parseInt(result[1], 16); 210 | var g = parseInt(result[2], 16); 211 | var b = parseInt(result[3], 16); 212 | r /= 255, g /= 255, b /= 255; 213 | var max = Math.max(r, g, b), 214 | min = Math.min(r, g, b); 215 | var h, s, l = (max + min) / 2; 216 | if (max == min) { 217 | h = s = 0; 218 | } else { 219 | var d = max - min; 220 | s = l > 0.5 ? d / (2 - max - min) : d / (max + min); 221 | switch (max) { 222 | case r: 223 | h = (g - b) / d + (g < b ? 6 : 0); 224 | break; 225 | case g: 226 | h = (b - r) / d + 2; 227 | break; 228 | case b: 229 | h = (r - g) / d + 4; 230 | break; 231 | } 232 | h /= 6; 233 | } 234 | s = s * 100; 235 | sat = Math.round(s); 236 | l = l * 100; 237 | light = Math.round(l); 238 | hue = Math.round(360 * h); 239 | } 240 | const hslToColor = () => { 241 | swatch.style.backgroundColor = getHSL(); 242 | hexValue = getHEX(); 243 | swatch.value = hexInput.value = satInput.style.backgroundColor = hexValue; 244 | metaThemeColor.setAttribute("content", hexValue); 245 | } 246 | const hexToColor = () => { 247 | hueInput.value = hue; 248 | satInput.value = sat; 249 | lightInput.value = light; 250 | swatch.style.backgroundColor = getHSL(); 251 | satInput.style.backgroundColor = getHEX(); 252 | } 253 | const getHEX = () => { 254 | return hslToHex(hue, sat, light); 255 | }; 256 | const getHSL = () => { 257 | return `hsl(${hue}, ${sat}%, ${light}%)`; 258 | }; 259 | const evList = () => { 260 | 261 | hueInput.addEventListener('input', () => { 262 | hue = hueInput.value; 263 | hslToColor(); 264 | }); 265 | satInput.addEventListener('input', () => { 266 | sat = satInput.value; 267 | hslToColor(); 268 | }); 269 | lightInput.addEventListener('input', () => { 270 | light = lightInput.value; 271 | hslToColor(); 272 | }); 273 | hexInput.addEventListener('input', () => { 274 | hexV = hexInput.value; 275 | if (hexV.length == 7) { 276 | hexToHsl(hexV); 277 | hexToColor(); 278 | } 279 | }); 280 | hslToColor(); 281 | document.querySelector("#save_btn").addEventListener("click", () => { 282 | saveEditorContent(); 283 | }) 284 | document.querySelector("#exp_btn").addEventListener("click", () => { 285 | exportData() 286 | }); 287 | document.querySelector("#res2_btn").addEventListener("click", () => { 288 | show_lrt(1); 289 | }); 290 | document.querySelector("#imp_btn").addEventListener("click", () => { 291 | document.querySelector("#imp_f").click() 292 | }); 293 | document.querySelector("#imp_f").addEventListener("change", () => { 294 | importData() 295 | }, false); 296 | chk_st.addEventListener("change",()=>{ 297 | customChanged = true; 298 | }); 299 | optc.addEventListener("change", () => { 300 | customChanged = true; 301 | let ch = optc.checked; 302 | opt1c.disabled = (ch) ? false : true; 303 | opt2c.disabled = (ch) ? false : true; 304 | hex_ccl.style.pointerEvents = (ch) ? "unset" : "none"; 305 | opt0c.disabled = (ch) ? false : true; 306 | }); 307 | opt0c.addEventListener("change", () => { 308 | customChanged = true; 309 | let ch = opt0c.checked; 310 | opt1c.checked = opt2c.checked = ch; 311 | opt1c.disabled = (ch) ? false : true; 312 | opt2c.disabled = (ch) ? false : true; 313 | }); 314 | opt0.addEventListener("change", () => { 315 | let ch = opt0.checked; 316 | opt1.checked = opt2.checked = ch; 317 | opt1.disabled = (ch) ? false : true; 318 | opt2.disabled = (ch) ? false : true; 319 | }); 320 | document.getElementById("can_lrt").onclick = () => { 321 | document.getElementById("mylrt").style.display = "none"; 322 | } 323 | // When the user clicks on the button, open the lrt 324 | document.getElementById("ok_lrt").onclick = () => { 325 | 326 | 327 | chrome.storage.local.clear(); 328 | location.reload(); 329 | dialog.hide(); 330 | } 331 | document.getElementById("clrp_apply").onclick = () => { 332 | if (currentisdefault) 333 | setInputColor(hexValue); 334 | else 335 | setInputColor(hexValue, true); 336 | clrp.hide(); 337 | } 338 | document.getElementById("clrp_cancel").onclick = () => { 339 | if (currentisdefault) 340 | metaThemeColor.setAttribute("content", hexInput_g.value); 341 | else 342 | metaThemeColor.setAttribute("content", hexInput_c.value); 343 | clrp.hide(); 344 | } 345 | document.getElementById("hex_global_cl").onclick = () => { 346 | currentisdefault = true; 347 | clrp.show(); 348 | hexToHsl(hexInput_g.value); 349 | hexToColor(); 350 | } 351 | document.getElementById("hex_custom_cl").onclick = () => { 352 | customChanged = true; 353 | currentisdefault = false; 354 | clrp.show(); 355 | hexToHsl(hexInput_c.value); 356 | hexToColor(); 357 | } 358 | } 359 | let messages = ["Reset color to default one on current website
You can edit below and change default color ,then click ok to confirm change", 360 | "Are you sure you want to reset ? ( you will lose all extension data like colors per hosts)", 361 | ] 362 | const show_lrt = (l) => { 363 | document.querySelector("#dialog>div>div").innerHTML = messages[l]; 364 | if (l == 0) document.getElementById("def_inp").value = defaultColor; 365 | dialog.show(); 366 | } 367 | 368 | const exportData = () => { 369 | chrome.storage.local.get(null, function (items) { 370 | var result = JSON.stringify(items); 371 | var url = 'data:application/json;base64,' + btoa(result); 372 | var date = new Date(); 373 | var le = document.createElement('a'); 374 | le.setAttribute('href', url); 375 | le.setAttribute('download', 'mti_' + (date.getUTCMonth() + 1) + '' + date.getUTCDate() + '_' + 376 | date.getHours() + '-' + date.getMinutes() + '.json'); 377 | le.click(); 378 | }); 379 | } 380 | const importData = () => { 381 | chrome.storage.local.clear(); 382 | var file = document.querySelector("#imp_f").files[0]; 383 | var reader = new FileReader(); 384 | reader.onload = function (progressEvent) { 385 | var test = this.result; 386 | var test2 = JSON.parse(test); 387 | chrome.storage.local.set(test2, function () { 388 | alert("MTI data imported .") 389 | }); 390 | } 391 | reader.readAsText(file); 392 | location.reload(); 393 | } 394 | const setInputColor = (c, l) => { 395 | if (!l) { 396 | hexInput_g.value = c; 397 | hex_gcl.style.backgroundColor = c; 398 | } else { 399 | hexInput_c.value = c; 400 | hex_ccl.style.backgroundColor = c; 401 | } 402 | } 403 | const getCurrentDomain = () => { 404 | var url = window.location.href; 405 | if (window.tab && window.tab.url) url = tab.url; 406 | console.log(url); 407 | if (url.match(/[^\/]+\/\/[^\/]+/) != undefined) 408 | return url.match(/[^\/]+\/\/[^\/]+/)[0]; 409 | } 410 | const loadEditorContent = () => { 411 | return dataStorage.load().then(function (injectionData) { 412 | console.log("Injection data " + injectionData); 413 | 414 | chrome.storage.local.get({ 415 | dfc: "#0878A5", 416 | opt: [true, true, false] 417 | }, function (items) { 418 | //Set domain 419 | dmn_inp.value = getCurrentDomain(); 420 | //Set color 421 | let dfcolor = items.dfc; 422 | setInputColor(dfcolor); 423 | hexToHsl(dfcolor); 424 | hexToColor(); 425 | metaThemeColor.setAttribute("content", dfcolor); 426 | //Set options 427 | let opt = items.opt; 428 | opt0.checked = opt[0], opt1.checked = opt[1], opt2.checked = opt[2]; 429 | 430 | console.log(injectionData); 431 | if (injectionData) { 432 | customChanged=true; 433 | console.log("injectionData found"); 434 | //alert(Object.values(injectionData) + " |\n "+ Object.keys(injectionData) +" |\n "+chk_st.checked +" |\n"+Array.isArray(injectionData.opt)); 435 | let color = injectionData.color; 436 | if (!color) color = dfcolor; 437 | setInputColor(color, true); 438 | hexToHsl(color); 439 | hexToColor(); 440 | metaThemeColor.setAttribute("content", color); 441 | let o = injectionData.opt; 442 | console.log(o[0]); 443 | optc.checked=o[0],opt0c.checked = o[1], opt1c.checked = o[2], opt2c.checked = o[3]; 444 | chk_st.checked = !injectionData.bl; 445 | currentInjectionData = injectionData; 446 | } else { 447 | chk_st.checked= true; 448 | optc.checked = false; 449 | setInputColor(dfcolor, true); 450 | //Disable custom checkboxes 451 | opt0c.disabled = true, opt1c.disabled = true, opt2c.disabled = true; 452 | //Disable custom color input 453 | hex_ccl.style.pointerEvents = "none"; 454 | } 455 | }); 456 | 457 | 458 | }); 459 | } 460 | const saveEditorContent = () => { 461 | ntoast.success('Options saved. Reload the website page to apply changes'); 462 | chrome.storage.local.set({ 463 | dfc: hexInput_g.value, 464 | opt: [opt0.checked, opt1.checked, opt2.checked] 465 | }) 466 | if (customChanged) { 467 | let newDomain = dmn_inp.value; 468 | if (currentInjectionData && currentInjectionData.domain !== newDomain) 469 | dataStorage.remove(currentInjectionData.domain); 470 | let injectionData = new InjectedData(newDomain, hexInput_c.value, [optc.checked, opt0c.checked, opt1c.checked, opt2c.checked], (!chk_st.checked)); 471 | currentInjectionData = injectionData; 472 | console.log(injectionData); 473 | //alert(Object.values(injectionData) + " |\n "+ Object.keys(injectionData) +" |\n "+chk_st.checked); 474 | dataStorage.save(injectionData); 475 | } 476 | 477 | 478 | } 479 | const dismBox = () => { 480 | document.getElementById("mylrt").style.display = "none"; 481 | } 482 | var clrp, dialog; 483 | var ntoast = new alert({ 484 | timeout: 60000, 485 | autoClose: false 486 | }); 487 | document.addEventListener("DOMContentLoaded", () => { 488 | chrome.tabs.query({ 489 | currentWindow: true, 490 | active: true 491 | }, function (tabs) { 492 | window.tab = tabs[0]; 493 | loadEditorContent().then(() => { 494 | evList(); 495 | }); 496 | }); 497 | new themeManager(); 498 | clrp = new modal("#clrp"); 499 | 500 | dialog = new modal("#dialog"); 501 | }) -------------------------------------------------------------------------------- /src/svg/icon256.svg: -------------------------------------------------------------------------------- 1 | --------------------------------------------------------------------------------