diff --git a/package.json b/package.json index 37fb3f94..359a6222 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,9 @@ }, "dependencies": { "@types/color": "^3.0.4", + "@types/dompurify": "^3.0.5", "@types/react": "^18.2.21", + "@types/sortablejs": "^1.15.7", "@types/webextension-polyfill": "^0.10.7", "autoprefixer": "^10.4.15", "color": "^4.2.3", @@ -43,6 +45,7 @@ "react": "^18.2.0", "sortablejs": "^1.15.0", "tailwindcss": "^3.3.3", + "ts-loader": "^9.5.1", "typescript": "^5.2.2" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2bac5a4a..40cbb681 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,16 +1,22 @@ lockfileVersion: '6.0' settings: - autoInstallPeers: false + autoInstallPeers: true excludeLinksFromLockfile: false dependencies: '@types/color': specifier: ^3.0.4 version: 3.0.6 + '@types/dompurify': + specifier: ^3.0.5 + version: 3.0.5 '@types/react': specifier: ^18.2.21 version: 18.2.40 + '@types/sortablejs': + specifier: ^1.15.7 + version: 1.15.7 '@types/webextension-polyfill': specifier: ^0.10.7 version: 0.10.7 @@ -44,6 +50,9 @@ dependencies: tailwindcss: specifier: ^3.3.3 version: 3.3.5 + ts-loader: + specifier: ^9.5.1 + version: 9.5.1(typescript@5.3.2)(webpack@5.89.0) typescript: specifier: ^5.2.2 version: 5.3.2 @@ -110,7 +119,6 @@ packages: /@discoveryjs/json-ext@0.5.7: resolution: {integrity: sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==} engines: {node: '>=10.0.0'} - dev: true /@eslint-community/eslint-utils@4.4.0(eslint@8.55.0): resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} @@ -209,7 +217,6 @@ packages: dependencies: '@jridgewell/gen-mapping': 0.3.3 '@jridgewell/trace-mapping': 0.3.20 - dev: true /@jridgewell/sourcemap-codec@1.4.15: resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} @@ -319,23 +326,26 @@ packages: '@types/color-convert': 2.0.3 dev: false + /@types/dompurify@3.0.5: + resolution: {integrity: sha512-1Wg0g3BtQF7sSb27fJQAKck1HECM6zV1EB66j8JH9i3LCjYabJa0FSdiSgsD5K/RbrsR0SiraKacLB+T8ZVYAg==} + dependencies: + '@types/trusted-types': 2.0.7 + dev: false + /@types/eslint-scope@3.7.7: resolution: {integrity: sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==} dependencies: '@types/eslint': 8.44.8 '@types/estree': 1.0.5 - dev: true /@types/eslint@8.44.8: resolution: {integrity: sha512-4K8GavROwhrYl2QXDXm0Rv9epkA8GBFu0EI+XrrnnuCl7u8CWBRusX7fXJfanhZTDWSAL24gDI/UqXyUM0Injw==} dependencies: '@types/estree': 1.0.5 '@types/json-schema': 7.0.15 - dev: true /@types/estree@1.0.5: resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} - dev: true /@types/istanbul-lib-coverage@2.0.6: resolution: {integrity: sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==} @@ -355,13 +365,11 @@ packages: /@types/json-schema@7.0.15: resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} - dev: true /@types/node@20.10.2: resolution: {integrity: sha512-37MXfxkb0vuIlRKHNxwCkb60PNBpR94u4efQuN4JgIAm66zfCDXGSAFCef9XUWFovX2R1ok6Z7MHhtdVXXkkIw==} dependencies: undici-types: 5.26.5 - dev: true /@types/prop-types@15.7.11: resolution: {integrity: sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==} @@ -379,6 +387,14 @@ packages: resolution: {integrity: sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==} dev: false + /@types/sortablejs@1.15.7: + resolution: {integrity: sha512-PvgWCx1Lbgm88FdQ6S7OGvLIjWS66mudKPlfdrWil0TjsO5zmoZmzoKiiwRShs1dwPgrlkr0N4ewuy0/+QUXYQ==} + dev: false + + /@types/trusted-types@2.0.7: + resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==} + dev: false + /@types/webextension-polyfill@0.10.7: resolution: {integrity: sha512-10ql7A0qzBmFB+F+qAke/nP1PIonS0TXZAOMVOxEUsm+lGSW6uwVcISFNa0I4Oyj0884TZVWGGMIWeXOVSNFHw==} dev: false @@ -402,19 +418,15 @@ packages: dependencies: '@webassemblyjs/helper-numbers': 1.11.6 '@webassemblyjs/helper-wasm-bytecode': 1.11.6 - dev: true /@webassemblyjs/floating-point-hex-parser@1.11.6: resolution: {integrity: sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==} - dev: true /@webassemblyjs/helper-api-error@1.11.6: resolution: {integrity: sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==} - dev: true /@webassemblyjs/helper-buffer@1.11.6: resolution: {integrity: sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA==} - dev: true /@webassemblyjs/helper-numbers@1.11.6: resolution: {integrity: sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==} @@ -422,11 +434,9 @@ packages: '@webassemblyjs/floating-point-hex-parser': 1.11.6 '@webassemblyjs/helper-api-error': 1.11.6 '@xtuc/long': 4.2.2 - dev: true /@webassemblyjs/helper-wasm-bytecode@1.11.6: resolution: {integrity: sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==} - dev: true /@webassemblyjs/helper-wasm-section@1.11.6: resolution: {integrity: sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==} @@ -435,23 +445,19 @@ packages: '@webassemblyjs/helper-buffer': 1.11.6 '@webassemblyjs/helper-wasm-bytecode': 1.11.6 '@webassemblyjs/wasm-gen': 1.11.6 - dev: true /@webassemblyjs/ieee754@1.11.6: resolution: {integrity: sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==} dependencies: '@xtuc/ieee754': 1.2.0 - dev: true /@webassemblyjs/leb128@1.11.6: resolution: {integrity: sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==} dependencies: '@xtuc/long': 4.2.2 - dev: true /@webassemblyjs/utf8@1.11.6: resolution: {integrity: sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==} - dev: true /@webassemblyjs/wasm-edit@1.11.6: resolution: {integrity: sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==} @@ -464,7 +470,6 @@ packages: '@webassemblyjs/wasm-opt': 1.11.6 '@webassemblyjs/wasm-parser': 1.11.6 '@webassemblyjs/wast-printer': 1.11.6 - dev: true /@webassemblyjs/wasm-gen@1.11.6: resolution: {integrity: sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==} @@ -474,7 +479,6 @@ packages: '@webassemblyjs/ieee754': 1.11.6 '@webassemblyjs/leb128': 1.11.6 '@webassemblyjs/utf8': 1.11.6 - dev: true /@webassemblyjs/wasm-opt@1.11.6: resolution: {integrity: sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==} @@ -483,7 +487,6 @@ packages: '@webassemblyjs/helper-buffer': 1.11.6 '@webassemblyjs/wasm-gen': 1.11.6 '@webassemblyjs/wasm-parser': 1.11.6 - dev: true /@webassemblyjs/wasm-parser@1.11.6: resolution: {integrity: sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==} @@ -494,14 +497,12 @@ packages: '@webassemblyjs/ieee754': 1.11.6 '@webassemblyjs/leb128': 1.11.6 '@webassemblyjs/utf8': 1.11.6 - dev: true /@webassemblyjs/wast-printer@1.11.6: resolution: {integrity: sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==} dependencies: '@webassemblyjs/ast': 1.11.6 '@xtuc/long': 4.2.2 - dev: true /@webpack-cli/configtest@2.1.1(webpack-cli@5.1.4)(webpack@5.89.0): resolution: {integrity: sha512-wy0mglZpDSiSS0XHrVR+BAdId2+yxPSoJW8fsna3ZpYSlufjvxnP4YbKTCBZnNIcGN4r6ZPXV55X4mYExOfLmw==} @@ -512,7 +513,6 @@ packages: dependencies: webpack: 5.89.0(webpack-cli@5.1.4) webpack-cli: 5.1.4(webpack@5.89.0) - dev: true /@webpack-cli/info@2.0.2(webpack-cli@5.1.4)(webpack@5.89.0): resolution: {integrity: sha512-zLHQdI/Qs1UyT5UBdWNqsARasIA+AaF8t+4u2aS2nEpBQh2mWIVb8qAklq0eUENnC5mOItrIB4LiS9xMtph18A==} @@ -523,7 +523,6 @@ packages: dependencies: webpack: 5.89.0(webpack-cli@5.1.4) webpack-cli: 5.1.4(webpack@5.89.0) - dev: true /@webpack-cli/serve@2.0.5(webpack-cli@5.1.4)(webpack@5.89.0): resolution: {integrity: sha512-lqaoKnRYBdo1UgDX8uF24AfGMifWK19TxPmM5FHc2vAGxrJ/qtyUyFBWoY1tISZdelsQ5fBcOusifo5o5wSJxQ==} @@ -538,15 +537,12 @@ packages: dependencies: webpack: 5.89.0(webpack-cli@5.1.4) webpack-cli: 5.1.4(webpack@5.89.0) - dev: true /@xtuc/ieee754@1.2.0: resolution: {integrity: sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==} - dev: true /@xtuc/long@4.2.2: resolution: {integrity: sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==} - dev: true /acorn-import-assertions@1.9.0(acorn@8.11.2): resolution: {integrity: sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==} @@ -554,7 +550,6 @@ packages: acorn: ^8 dependencies: acorn: 8.11.2 - dev: true /acorn-jsx@5.3.2(acorn@8.11.2): resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} @@ -568,10 +563,11 @@ packages: resolution: {integrity: sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==} engines: {node: '>=0.4.0'} hasBin: true - dev: true - /ajv-formats@2.1.1: + /ajv-formats@2.1.1(ajv@8.12.0): resolution: {integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==} + peerDependencies: + ajv: ^8.0.0 peerDependenciesMeta: ajv: optional: true @@ -585,7 +581,6 @@ packages: ajv: ^6.9.1 dependencies: ajv: 6.12.6 - dev: true /ajv-keywords@5.1.0(ajv@8.12.0): resolution: {integrity: sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==} @@ -603,7 +598,6 @@ packages: fast-json-stable-stringify: 2.1.0 json-schema-traverse: 0.4.1 uri-js: 4.4.1 - dev: true /ajv@8.12.0: resolution: {integrity: sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==} @@ -624,7 +618,6 @@ packages: engines: {node: '>=8'} dependencies: color-convert: 2.0.1 - dev: true /any-promise@1.3.0: resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} @@ -696,7 +689,6 @@ packages: /buffer-from@1.1.2: resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} - dev: true /callsites@3.1.0: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} @@ -717,7 +709,6 @@ packages: dependencies: ansi-styles: 4.3.0 supports-color: 7.2.0 - dev: true /chokidar@3.5.3: resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} @@ -736,7 +727,6 @@ packages: /chrome-trace-event@1.0.3: resolution: {integrity: sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==} engines: {node: '>=6.0'} - dev: true /ci-info@3.9.0: resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} @@ -750,7 +740,6 @@ packages: is-plain-object: 2.0.4 kind-of: 6.0.3 shallow-clone: 3.0.1 - dev: true /color-convert@2.0.1: resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} @@ -778,16 +767,13 @@ packages: /colorette@2.0.20: resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} - dev: true /commander@10.0.1: resolution: {integrity: sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==} engines: {node: '>=14'} - dev: true /commander@2.20.3: resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} - dev: true /commander@4.1.1: resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} @@ -819,7 +805,6 @@ packages: path-key: 3.1.1 shebang-command: 2.0.0 which: 2.0.2 - dev: true /css-loader@6.8.1(webpack@5.89.0): resolution: {integrity: sha512-xDAXtEVGlD0gJ07iclwWVkLoZOpEvAWaSyf6W18S2pOC//K8+qUDIx8IIT3D+HjnmkJPQeesOPv5aiUaJsCM2g==} @@ -903,17 +888,14 @@ packages: dependencies: graceful-fs: 4.2.11 tapable: 2.2.1 - dev: true /envinfo@7.11.0: resolution: {integrity: sha512-G9/6xF1FPbIw0TtalAMaVPpiq2aDEuKLXM314jPVAO9r2fo2a4BLqMNkmRS7O/xPPZ+COAhGIz3ETvHEV3eUcg==} engines: {node: '>=4'} hasBin: true - dev: true /es-module-lexer@1.4.1: resolution: {integrity: sha512-cXLGjP0c4T3flZJKQSuziYoq7MlT+rnvfZjfp7h+I7K9BNX54kP9nyWvdbwjQ4u1iWbOL4u96fgeZLToQlZC7w==} - dev: true /escalade@3.1.1: resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} @@ -939,7 +921,6 @@ packages: dependencies: esrecurse: 4.3.0 estraverse: 4.3.0 - dev: true /eslint-scope@7.2.2: resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==} @@ -1038,17 +1019,14 @@ packages: engines: {node: '>=4.0'} dependencies: estraverse: 5.3.0 - dev: true /estraverse@4.3.0: resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==} engines: {node: '>=4.0'} - dev: true /estraverse@5.3.0: resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} engines: {node: '>=4.0'} - dev: true /esutils@2.0.3: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} @@ -1058,11 +1036,9 @@ packages: /events@3.3.0: resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} engines: {node: '>=0.8.x'} - dev: true /fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} - dev: true /fast-glob@3.3.2: resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} @@ -1076,7 +1052,6 @@ packages: /fast-json-stable-stringify@2.1.0: resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} - dev: true /fast-levenshtein@2.0.6: resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} @@ -1085,7 +1060,6 @@ packages: /fastest-levenshtein@1.0.16: resolution: {integrity: sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==} engines: {node: '>= 4.9.1'} - dev: true /fastq@1.15.0: resolution: {integrity: sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==} @@ -1122,7 +1096,6 @@ packages: dependencies: locate-path: 5.0.0 path-exists: 4.0.0 - dev: true /find-up@5.0.0: resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} @@ -1144,7 +1117,6 @@ packages: /flat@5.0.2: resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==} hasBin: true - dev: true /flatted@3.2.9: resolution: {integrity: sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==} @@ -1181,7 +1153,6 @@ packages: /glob-to-regexp@0.4.1: resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} - dev: true /glob@7.1.6: resolution: {integrity: sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==} @@ -1225,7 +1196,6 @@ packages: /graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} - dev: true /graphemer@1.4.0: resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} @@ -1234,7 +1204,6 @@ packages: /has-flag@4.0.0: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} engines: {node: '>=8'} - dev: true /hasown@2.0.0: resolution: {integrity: sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==} @@ -1283,7 +1252,6 @@ packages: dependencies: pkg-dir: 4.2.0 resolve-cwd: 3.0.0 - dev: true /imurmurhash@0.1.4: resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} @@ -1307,7 +1275,6 @@ packages: /interpret@3.1.1: resolution: {integrity: sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==} engines: {node: '>=10.13.0'} - dev: true /is-arrayish@0.3.2: resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==} @@ -1348,16 +1315,13 @@ packages: engines: {node: '>=0.10.0'} dependencies: isobject: 3.0.1 - dev: true /isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} - dev: true /isobject@3.0.1: resolution: {integrity: sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==} engines: {node: '>=0.10.0'} - dev: true /jest-util@29.7.0: resolution: {integrity: sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==} @@ -1378,7 +1342,6 @@ packages: '@types/node': 20.10.2 merge-stream: 2.0.0 supports-color: 8.1.1 - dev: true /jest-worker@29.7.0: resolution: {integrity: sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==} @@ -1412,11 +1375,9 @@ packages: /json-parse-even-better-errors@2.3.1: resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} - dev: true /json-schema-traverse@0.4.1: resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} - dev: true /json-schema-traverse@1.0.0: resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} @@ -1441,7 +1402,6 @@ packages: /kind-of@6.0.3: resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} engines: {node: '>=0.10.0'} - dev: true /levn@0.4.1: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} @@ -1474,7 +1434,6 @@ packages: /loader-runner@4.3.0: resolution: {integrity: sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==} engines: {node: '>=6.11.5'} - dev: true /loader-utils@2.0.4: resolution: {integrity: sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==} @@ -1496,7 +1455,6 @@ packages: engines: {node: '>=8'} dependencies: p-locate: 4.1.0 - dev: true /locate-path@6.0.0: resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} @@ -1521,11 +1479,9 @@ packages: engines: {node: '>=10'} dependencies: yallist: 4.0.0 - dev: true /merge-stream@2.0.0: resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} - dev: true /merge2@1.4.1: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} @@ -1541,14 +1497,12 @@ packages: /mime-db@1.52.0: resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} engines: {node: '>= 0.6'} - dev: true /mime-types@2.1.35: resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} engines: {node: '>= 0.6'} dependencies: mime-db: 1.52.0 - dev: true /mini-css-extract-plugin@2.7.6(webpack@5.89.0): resolution: {integrity: sha512-Qk7HcgaPkGG6eD77mLvZS1nmxlao3j+9PkrT9Uc7HAE1id3F41+DdBRYRYkbyfNRGzm8/YWtzhw7nVPmwhqTQw==} @@ -1599,7 +1553,6 @@ packages: /neo-async@2.6.2: resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} - dev: true /node-releases@2.0.14: resolution: {integrity: sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==} @@ -1723,7 +1676,6 @@ packages: engines: {node: '>=6'} dependencies: p-try: 2.2.0 - dev: true /p-limit@3.1.0: resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} @@ -1737,7 +1689,6 @@ packages: engines: {node: '>=8'} dependencies: p-limit: 2.3.0 - dev: true /p-locate@5.0.0: resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} @@ -1749,7 +1700,6 @@ packages: /p-try@2.2.0: resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} engines: {node: '>=6'} - dev: true /parent-module@1.0.1: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} @@ -1761,7 +1711,6 @@ packages: /path-exists@4.0.0: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} engines: {node: '>=8'} - dev: true /path-is-absolute@1.0.1: resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} @@ -1770,7 +1719,6 @@ packages: /path-key@3.1.1: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} - dev: true /path-parse@1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} @@ -1802,7 +1750,6 @@ packages: engines: {node: '>=8'} dependencies: find-up: 4.1.0 - dev: true /postcss-import@15.1.0(postcss@8.4.32): resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==} @@ -1926,7 +1873,6 @@ packages: /punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} - dev: true /queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} @@ -1935,7 +1881,6 @@ packages: resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} dependencies: safe-buffer: 5.2.1 - dev: true /react@18.2.0: resolution: {integrity: sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==} @@ -1961,7 +1906,6 @@ packages: engines: {node: '>= 10.13.0'} dependencies: resolve: 1.22.8 - dev: true /require-from-string@2.0.2: resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} @@ -1973,7 +1917,6 @@ packages: engines: {node: '>=8'} dependencies: resolve-from: 5.0.0 - dev: true /resolve-from@4.0.0: resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} @@ -1983,7 +1926,6 @@ packages: /resolve-from@5.0.0: resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} engines: {node: '>=8'} - dev: true /resolve@1.22.8: resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} @@ -2011,7 +1953,6 @@ packages: /safe-buffer@5.2.1: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} - dev: true /sass-loader@13.3.2(sass@1.69.5)(webpack@5.89.0): resolution: {integrity: sha512-CQbKl57kdEv+KDLquhC+gE3pXt74LEAzm+tzywcA0/aHZuub8wTErbjAoNI57rPUWRYRNC5WUnNl8eGJNbDdwg==} @@ -2054,7 +1995,6 @@ packages: '@types/json-schema': 7.0.15 ajv: 6.12.6 ajv-keywords: 3.5.2(ajv@6.12.6) - dev: true /schema-utils@4.2.0: resolution: {integrity: sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==} @@ -2062,7 +2002,7 @@ packages: dependencies: '@types/json-schema': 7.0.15 ajv: 8.12.0 - ajv-formats: 2.1.1 + ajv-formats: 2.1.1(ajv@8.12.0) ajv-keywords: 5.1.0(ajv@8.12.0) dev: true @@ -2072,32 +2012,27 @@ packages: hasBin: true dependencies: lru-cache: 6.0.0 - dev: true /serialize-javascript@6.0.1: resolution: {integrity: sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==} dependencies: randombytes: 2.1.0 - dev: true /shallow-clone@3.0.1: resolution: {integrity: sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==} engines: {node: '>=8'} dependencies: kind-of: 6.0.3 - dev: true /shebang-command@2.0.0: resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} engines: {node: '>=8'} dependencies: shebang-regex: 3.0.0 - dev: true /shebang-regex@3.0.0: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} - dev: true /simple-swizzle@0.2.2: resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==} @@ -2123,12 +2058,15 @@ packages: dependencies: buffer-from: 1.1.2 source-map: 0.6.1 - dev: true /source-map@0.6.1: resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} engines: {node: '>=0.10.0'} - dev: true + + /source-map@0.7.4: + resolution: {integrity: sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==} + engines: {node: '>= 8'} + dev: false /strip-ansi@6.0.1: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} @@ -2170,14 +2108,12 @@ packages: engines: {node: '>=8'} dependencies: has-flag: 4.0.0 - dev: true /supports-color@8.1.1: resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} engines: {node: '>=10'} dependencies: has-flag: 4.0.0 - dev: true /supports-preserve-symlinks-flag@1.0.0: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} @@ -2217,7 +2153,6 @@ packages: /tapable@2.2.1: resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} engines: {node: '>=6'} - dev: true /terser-webpack-plugin@5.3.9(webpack@5.89.0): resolution: {integrity: sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA==} @@ -2241,7 +2176,6 @@ packages: serialize-javascript: 6.0.1 terser: 5.24.0 webpack: 5.89.0(webpack-cli@5.1.4) - dev: true /terser@5.24.0: resolution: {integrity: sha512-ZpGR4Hy3+wBEzVEnHvstMvqpD/nABNelQn/z2r0fjVWGQsN3bpOLzQlqDxmb4CDZnXq5lpjnQ+mHQLAOpfM5iw==} @@ -2252,7 +2186,6 @@ packages: acorn: 8.11.2 commander: 2.20.3 source-map-support: 0.5.21 - dev: true /text-table@0.2.0: resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} @@ -2281,6 +2214,22 @@ packages: resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} dev: false + /ts-loader@9.5.1(typescript@5.3.2)(webpack@5.89.0): + resolution: {integrity: sha512-rNH3sK9kGZcH9dYzC7CewQm4NtxJTjSEVRJ2DyBZR7f8/wcta+iV44UPCXc5+nzDzivKtlzV6c9P4e+oFhDLYg==} + engines: {node: '>=12.0.0'} + peerDependencies: + typescript: '*' + webpack: ^5.0.0 + dependencies: + chalk: 4.1.2 + enhanced-resolve: 5.15.0 + micromatch: 4.0.5 + semver: 7.5.4 + source-map: 0.7.4 + typescript: 5.3.2 + webpack: 5.89.0(webpack-cli@5.1.4) + dev: false + /tslib@2.6.2: resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} dev: false @@ -2305,7 +2254,6 @@ packages: /undici-types@5.26.5: resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} - dev: true /update-browserslist-db@1.0.13(browserslist@4.22.1): resolution: {integrity: sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==} @@ -2321,7 +2269,6 @@ packages: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} dependencies: punycode: 2.3.1 - dev: true /util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} @@ -2332,7 +2279,6 @@ packages: dependencies: glob-to-regexp: 0.4.1 graceful-fs: 4.2.11 - dev: true /webextension-polyfill@0.10.0: resolution: {integrity: sha512-c5s35LgVa5tFaHhrZDnr3FpQpjj1BB+RXhLTYUxGqBVN460HkbM8TBtEqdXWbpTKfzwCcjAZVF7zXCYSKtcp9g==} @@ -2369,7 +2315,6 @@ packages: rechoir: 0.8.0 webpack: 5.89.0(webpack-cli@5.1.4) webpack-merge: 5.10.0 - dev: true /webpack-merge@5.10.0: resolution: {integrity: sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==} @@ -2378,12 +2323,10 @@ packages: clone-deep: 4.0.1 flat: 5.0.2 wildcard: 2.0.1 - dev: true /webpack-sources@3.2.3: resolution: {integrity: sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==} engines: {node: '>=10.13.0'} - dev: true /webpack@5.89.0(webpack-cli@5.1.4): resolution: {integrity: sha512-qyfIC10pOr70V+jkmud8tMfajraGCZMBWJtrmuBymQKCrLTRejBI8STDp1MCyZu/QTdZSeacCQYpYNQVOzX5kw==} @@ -2424,7 +2367,6 @@ packages: - '@swc/core' - esbuild - uglify-js - dev: true /which@2.0.2: resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} @@ -2432,18 +2374,15 @@ packages: hasBin: true dependencies: isexe: 2.0.0 - dev: true /wildcard@2.0.1: resolution: {integrity: sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==} - dev: true /wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} /yallist@4.0.0: resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} - dev: true /yaml@2.3.4: resolution: {integrity: sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA==} diff --git a/src/SEQTA.js b/src/SEQTA.ts similarity index 78% rename from src/SEQTA.js rename to src/SEQTA.ts index 2016891b..cc5c587c 100644 --- a/src/SEQTA.js +++ b/src/SEQTA.ts @@ -2,32 +2,38 @@ import browser from 'webextension-polyfill'; import { animate, spring, stagger } from 'motion'; import Color from 'color'; -import Sortable, { AutoScroll } from 'sortablejs/modular/sortable.core.esm.js'; +import Sortable from 'sortablejs'; import ShortcutLinks from './seqta/content/links.json'; import MenuitemSVGKey from './seqta/content/MenuItemSVGKey.json'; -import stringToHTML from './seqta/utils/stringToHTML.js'; -import loading, { AppendLoadingSymbol } from './seqta/ui/Loading.js'; -import { response } from './seqta/utils/GetPrefs.js'; -import { onError } from './seqta/utils/onError.js'; +import stringToHTML from './seqta/utils/stringToHTML'; +import loading, { AppendLoadingSymbol } from './seqta/ui/Loading'; +import { response } from './seqta/utils/GetPrefs'; +import { onError } from './seqta/utils/onError'; // Icons -import assessmentsicon from './seqta/icons/assessmentsIcon.js'; -import coursesicon from './seqta/icons/coursesIcon.js'; -import StorageListener from './seqta/utils/StorageListener.js'; -import { MessageHandler } from './seqta/utils/MessageListener.js'; -import { updateBgDurations } from './seqta/ui/Animation.js'; -import { updateAllColors } from './seqta/ui/colors/Manager.js'; -import { appendBackgroundToUI } from './seqta/ui/ImageBackgrounds.js'; -import { enableCurrentTheme } from './seqta/ui/Themes.js'; +import assessmentsicon from './seqta/icons/assessmentsIcon'; +import coursesicon from './seqta/icons/coursesIcon'; +import StorageListener from './seqta/utils/StorageListener'; +import { MessageHandler } from './seqta/utils/MessageListener'; +import { updateBgDurations } from './seqta/ui/Animation'; +import { updateAllColors } from './seqta/ui/colors/Manager'; +import { appendBackgroundToUI } from './seqta/ui/ImageBackgrounds'; +import { enableCurrentTheme } from './seqta/ui/Themes'; + +declare global { + interface Window { + chrome?: any; + } +} export let isChrome = window.chrome; let SettingsClicked = false; export let MenuOptionsOpen = false; let UserInitalCode = ''; let currentSelectedDate = new Date(); -let LessonInterval; -export let DarkMode; +let LessonInterval: any; +export let DarkMode: boolean; var MenuItemMutation = false; var NonSEQTAPage = false; @@ -52,7 +58,7 @@ document.addEventListener( enableCurrentTheme(); const result = browser.storage.local.get() - function open (items) { + function open (items: any) { main(items); } result.then(open, onError) @@ -67,19 +73,20 @@ document.addEventListener( true, ); -function delay(ms) { +function delay(ms: number) { return new Promise((resolve) => setTimeout(resolve, ms)); } -function SetDisplayNone(ElementName) { +function SetDisplayNone(ElementName: string) { return `li[data-key=${ElementName}]{display:var(--menuHidden) !important; transition: 1s;}`; } -function animbkEnable(item) { +function animbkEnable(item: any) { if (item.animatedbk) { CreateBackground(); } else { RemoveBackground(); + // @ts-ignore Element always exists document.getElementById('container').style.background = 'var(--background-secondary)'; } } @@ -87,9 +94,9 @@ function animbkEnable(item) { export function ApplyCSSToHiddenMenuItems() { var stylesheetInnerText = ''; const result = browser.storage.local.get() - function open (result) { + function open (result: any) { for (let i = 0; i < Object.keys(result.menuitems).length; i++) { - if (!Object.values(result.menuitems)[i].toggle) { + if (!Object.values(result.menuitems)[i].toggle) { stylesheetInnerText += SetDisplayNone(Object.keys(result.menuitems)[i]); console.log( `[BetterSEQTA+] Hiding ${ @@ -113,7 +120,7 @@ function OpenWhatsNewPopup() { const container = document.createElement('div'); container.classList.add('whatsnewContainer'); - var header = stringToHTML(`
+ var header: any = stringToHTML(`

What's New

BetterSEQTA+ V${browser.runtime.getManifest().version}

`).firstChild; @@ -134,7 +141,7 @@ function OpenWhatsNewPopup() { let textcontainer = document.createElement('div'); textcontainer.classList.add('whatsnewTextContainer'); - let textheader = stringToHTML( + let textheader: any = stringToHTML( '

DESIGN OVERHAUL

', ).firstChild; textcontainer.append(textheader); @@ -235,19 +242,19 @@ function OpenWhatsNewPopup() { container.append(header); container.append(imagecont); container.append(textcontainer); - container.append(text); - container.append(footer); + container.append(text as ChildNode); + container.append(footer as ChildNode); container.append(exitbutton); background.append(container); - document.getElementById('container').append(background); + document.getElementById('container')!.append(background); let bkelement = document.getElementById('whatsnewbk'); let popup = document.getElementsByClassName('whatsnewContainer')[0]; animate( - [popup, bkelement], + [popup, bkelement as HTMLElement], { scale: [0, 1], opacity: [0, 1] }, { easing: spring({ stiffness: 220, damping: 18 }) } ); @@ -264,7 +271,7 @@ function OpenWhatsNewPopup() { browser.storage.local.remove(['justupdated']); - bkelement.addEventListener('click', function (event) { + bkelement!.addEventListener('click', function (event) { // Check if the click event originated from the element itself and not any of its children if (event.target === bkelement) { DeleteWhatsNew(); @@ -272,7 +279,7 @@ function OpenWhatsNewPopup() { }); var closeelement = document.getElementById('whatsnewclosebutton'); - closeelement.addEventListener('click', function () { + closeelement!.addEventListener('click', function () { DeleteWhatsNew(); }); } @@ -280,16 +287,16 @@ function OpenWhatsNewPopup() { async function finishLoad() { try { var loadingbk = document.getElementById('loading'); - loadingbk.style.opacity = '0'; + loadingbk!.style.opacity = '0'; await delay(501); - loadingbk.remove(); + loadingbk!.remove(); } catch (err) { console.log(err); } const result = browser.storage.local.get(['justupdated']); - function open (result) { + function open (result: any) { if (result.justupdated && !document.getElementById('whatsnewbk')) { OpenWhatsNewPopup(); } @@ -302,11 +309,11 @@ async function DeleteWhatsNew() { const popup = document.getElementsByClassName('whatsnewContainer')[0]; animate( - [popup, bkelement], + [popup, bkelement!], { opacity: [1, 0], scale: [1, 0] }, { easing: [.22, .03, .26, 1] } ).finished.then(() => { - bkelement.remove(); + bkelement!.remove(); }); } @@ -321,17 +328,17 @@ export function CreateBackground() { var bk = document.createElement('div'); bk.classList.add('bg'); - bklocation.insertBefore(bk, menu); + bklocation!.insertBefore(bk, menu); var bk2 = document.createElement('div'); bk2.classList.add('bg'); bk2.classList.add('bg2'); - bklocation.insertBefore(bk2, menu); + bklocation!.insertBefore(bk2, menu); var bk3 = document.createElement('div'); bk3.classList.add('bg'); bk3.classList.add('bg3'); - bklocation.insertBefore(bk3, menu); + bklocation!.insertBefore(bk3, menu); } export function RemoveBackground() { @@ -346,7 +353,7 @@ export function RemoveBackground() { console.log('it deleted???') } -export function waitForElm(selector) { +export function waitForElm(selector: any) { return new Promise((resolve) => { if (document.querySelector(selector)) { return resolve(document.querySelector(selector)); @@ -366,7 +373,7 @@ export function waitForElm(selector) { }); } -async function RunColourCheck(element) { +async function RunColourCheck(element: any) { if ( typeof element.contentDocument.documentElement.childNodes[1] == 'undefined' ) { @@ -376,7 +383,7 @@ async function RunColourCheck(element) { element.contentDocument.documentElement.childNodes[1].style.color = 'white'; } } -export function GetCSSElement (file) { +export function GetCSSElement (file: string) { const cssFile = browser.runtime.getURL(file) const fileref = document.createElement('link') fileref.setAttribute('rel', 'stylesheet') @@ -392,11 +399,12 @@ function removeThemeTagsFromNotices () { // Iterates through the array, applying the iFrame css for (const item of userHTMLArray) { // Grabs the HTML of the body tag - const body = item.contentWindow.document.querySelectorAll('body')[0] + const item1 = item as HTMLIFrameElement + const body = item1.contentWindow!.document.querySelectorAll('body')[0] if (body) { // Replaces the theme tag with nothing const bodyText = body.innerHTML - body.innerhtml = bodyText.replace(/\[\[[\w]+[:][\w]+[\]\]]+/g, '').replace(/ +/, ' ') + body.innerHTML = bodyText.replace(/\[\[[\w]+[:][\w]+[\]\]]+/g, '').replace(/ +/, ' ') } } } @@ -408,42 +416,46 @@ function CheckiFrameItems() { const observer = new MutationObserver(function (mutations_list) { mutations_list.forEach(function (mutation) { mutation.addedNodes.forEach(function (added_node) { - if (added_node.tagName == 'IFRAME') { + const node = added_node as HTMLElement + if (node.tagName == 'IFRAME') { const result = browser.storage.local.get('DarkMode'); - function open (result) { + function open (result: any) { DarkMode = result.DarkMode; + const node = added_node as HTMLIFrameElement if (DarkMode) { - RunColourCheck(added_node); + RunColourCheck(node); + const childNode = node.contentDocument!.documentElement.childNodes[1] as HTMLElement if ( - added_node.contentDocument.documentElement.childNodes[1].style + childNode.style .color != 'white' ) { - added_node.contentDocument.documentElement.childNodes[1].style.color = + childNode.style.color = 'white'; } + const innerHTMLNode = node.contentDocument!.documentElement.firstChild! as HTMLElement if ( - !added_node.contentDocument.documentElement.firstChild.innerHTML.includes( + !innerHTMLNode.innerHTML.includes( 'iframe.css', ) ) { - added_node.contentDocument.documentElement.firstChild.appendChild( + innerHTMLNode.appendChild( fileref, ); } added_node.addEventListener('load', function () { if ( - added_node.contentDocument.documentElement.childNodes[1].style + childNode.style .color != 'white' ) { - added_node.contentDocument.documentElement.childNodes[1].style.color = + childNode.style.color = 'white'; } if ( - !added_node.contentDocument.documentElement.firstChild.innerHTML.includes( + !innerHTMLNode.innerHTML.includes( 'iframe.css', ) ) { - added_node.contentDocument.documentElement.firstChild.appendChild( + innerHTMLNode.appendChild( fileref, ); } @@ -462,20 +474,21 @@ function CheckiFrameItems() { }); } -function SortMessagePageItems(messagesParentElement) { +function SortMessagePageItems(messagesParentElement: any) { let filterbutton = document.createElement('div'); filterbutton.classList.add('messages-filterbutton'); filterbutton.innerText = 'Filter'; let header = document.getElementsByClassName( 'MessageList__MessageList___3DxoC', - )[0].firstChild; + )[0].firstChild as HTMLElement; header.append(filterbutton); const observer = new MutationObserver(function (mutations_list) { mutations_list.forEach(function (mutation) { mutation.addedNodes.forEach(function (added_node) { - if (added_node.dataset.message) { + const node = added_node as HTMLElement + if (node.dataset.message) { // Check if added_node.firstChild.title is in block list } }); @@ -495,13 +508,13 @@ async function LoadPageElements() { case 'news': { console.log('[BetterSEQTA+] Started Init'); const result = browser.storage.local.get() - function open (result) { + function open (result: any) { if (result.onoff) { SendNewsPage(); // Sends similar HTTP Post Request for the notices const result = browser.storage.local.get() - function open (result) { + function open (result: any) { if (result.notificationcollector) { enableNotificationCollector(); } @@ -526,7 +539,7 @@ async function LoadPageElements() { // Sends similar HTTP Post Request for the notices const result1 = browser.storage.local.get() - function open1(result) { + function open1(result: any) { if (result.notificationcollector) { enableNotificationCollector(); } @@ -539,8 +552,9 @@ async function LoadPageElements() { const observer = new MutationObserver(function (mutations_list) { mutations_list.forEach(function (mutation) { mutation.addedNodes.forEach(function (added_node) { - if (added_node.classList.contains('messages')) { - let element = document.getElementById('title').firstChild; + const node = added_node as HTMLElement + if (node.classList.contains('messages')) { + let element = document.getElementById('title')!.firstChild as HTMLElement; element.innerText = 'Direct Messages'; document.title = 'Direct Messages ― SEQTA Learn'; SortMessagePageItems(added_node); @@ -556,9 +570,9 @@ async function LoadPageElements() { } ); }); - } else if (added_node.classList.contains('notices')) { + } else if (node.classList.contains('notices')) { CheckNoticeTextColour(added_node); - } else if (added_node.classList.contains('dashboard')) { + } else if (node.classList.contains('dashboard')) { let ranOnce = false; waitForElm('.dashlet').then(() => { if (ranOnce) return; @@ -573,7 +587,7 @@ async function LoadPageElements() { } ); }); - } else if (added_node.classList.contains('documents')) { + } else if (node.classList.contains('documents')) { let ranOnce = false; waitForElm('.document').then(() => { if (ranOnce) return; @@ -588,7 +602,7 @@ async function LoadPageElements() { } ); }); - } else if (added_node.classList.contains('reports')) { + } else if (node.classList.contains('reports')) { let ranOnce = false; waitForElm('.report').then(() => { if (ranOnce) return; @@ -608,24 +622,25 @@ async function LoadPageElements() { }); }); - observer.observe(document.querySelector('#main'), { + observer.observe(document.querySelector('#main') as HTMLElement, { subtree: false, childList: true, }); } -function CheckNoticeTextColour(notice) { +function CheckNoticeTextColour(notice: any) { const observer = new MutationObserver(function (mutations_list) { mutations_list.forEach(function (mutation) { mutation.addedNodes.forEach(function (added_node) { + const node = added_node as HTMLElement; const result = browser.storage.local.get(['DarkMode']) - function open (result) { + function open (result: any) { DarkMode = result.DarkMode; - if (added_node.classList.contains('notice')) { - var hex = added_node.style.cssText.split(' ')[1]; + if (node.classList.contains('notice')) { + var hex = node.style.cssText.split(' ')[1]; var threshold = GetThresholdOfColor(hex); if (DarkMode && threshold < 100) { - added_node.style.cssText = '--color: undefined;'; + node.style.cssText = '--color: undefined;'; } } } @@ -649,11 +664,11 @@ export function tryLoad() { finishLoad(); }); - waitForElm('[data-key=welcome]').then((elm) => { + waitForElm('[data-key=welcome]').then((elm: any) => { elm.classList.remove('active'); }); - waitForElm('.code').then((elm) => { + waitForElm('.code').then((elm: any) => { if (!elm.innerText.includes('BetterSEQTA')) LoadPageElements(); }); @@ -668,18 +683,19 @@ export function tryLoad() { true, ); const observer = new MutationObserver(() => { documentTextColor() }) - observer.observe(document.getElementById('toolbar'), { attributes: true, childList: true, subtree: true }) + observer.observe(document.getElementById('toolbar')!, { attributes: true, childList: true, subtree: true }) } -function ChangeMenuItemPositions(storage) { +function ChangeMenuItemPositions(storage: any) { let menuorder = storage; - var menuList = document.querySelector('#menu').firstChild.childNodes; + var menuList = document.querySelector('#menu')!.firstChild!.childNodes; let listorder = []; for (let i = 0; i < menuList.length; i++) { + const menu = menuList[i] as HTMLElement - let a = menuorder.indexOf(menuList[i].dataset.key); + let a = menuorder.indexOf(menu.dataset.key); listorder.push(a); } @@ -689,29 +705,32 @@ function ChangeMenuItemPositions(storage) { newArr[listorder[i]] = menuList[i]; } - let listItemsDOM = document.getElementById('menu').firstChild; + let listItemsDOM = document.getElementById('menu')!.firstChild; for (let i = 0; i < newArr.length; i++) { const element = newArr[i]; if (element) { - element.setAttribute('data-checked', 'true'); - listItemsDOM.appendChild(element); + const elem = element as HTMLElement + elem.setAttribute('data-checked', 'true'); + listItemsDOM!.appendChild(element); } } } export async function ObserveMenuItemPosition() { const result = browser.storage.local.get() - function open (result) { + function open (result: any) { let menuorder = result.menuorder; if (menuorder && result.onoff) { const observer = new MutationObserver(function (mutations_list) { mutations_list.forEach(function (mutation) { mutation.addedNodes.forEach(function (added_node) { - if (!added_node?.dataset?.checked && !MenuOptionsOpen) { - if (MenuitemSVGKey[added_node?.dataset?.key]) { + const node = added_node as HTMLElement + if (!node?.dataset?.checked && !MenuOptionsOpen) { + const key = MenuitemSVGKey[node?.dataset?.key! as keyof typeof MenuitemSVGKey] + if (key) { ReplaceMenuSVG( - added_node, - MenuitemSVGKey[added_node.dataset.key], + node, + MenuitemSVGKey[node.dataset.key as keyof typeof MenuitemSVGKey], ); } ChangeMenuItemPositions(menuorder); @@ -720,7 +739,7 @@ export async function ObserveMenuItemPosition() { }); }); - observer.observe(document.querySelector('#menu').firstChild, { + observer.observe(document.querySelector('#menu')!.firstChild!, { subtree: true, childList: true, }); @@ -729,7 +748,7 @@ export async function ObserveMenuItemPosition() { result.then(open, onError) } -function main(storedSetting) { +function main(storedSetting: any) { const onoff = storedSetting.onoff; DarkMode = storedSetting.DarkMode; @@ -841,68 +860,76 @@ async function CheckLoadOnPeriods() { } export function closeSettings() { - var extensionsettings = document.getElementById('ExtensionPopup'); + const ExtensionSettings = document.getElementById('ExtensionPopup')!; + const ExtensionIframe = document.getElementById('ExtensionIframe') as HTMLIFrameElement; if (SettingsClicked == true) { - extensionsettings.classList.add('hide'); + ExtensionSettings!.classList.add('hide'); animate( '#ExtensionPopup', { opacity: [1, 0], scale: [1, 0] }, { easing: spring({ stiffness: 220, damping: 18 }) } ); SettingsClicked = false; - document.getElementById('ExtensionIframe').contentWindow.postMessage('popupClosed', '*'); + + if (ExtensionIframe.contentWindow) { + ExtensionIframe.contentWindow.postMessage('popupClosed', '*'); + } } - extensionsettings.classList.add('hide'); + ExtensionSettings!.classList.add('hide'); } function addExtensionSettings() { const link = GetCSSElement('interface/popup.css'); - document.querySelector('html').appendChild(link); + document.querySelector('html')!.appendChild(link); const extensionPopup = document.createElement('div'); extensionPopup.classList.add('outside-container', 'hide'); extensionPopup.id = 'ExtensionPopup'; document.body.appendChild(extensionPopup); - const extensionIframe = document.createElement('iframe'); + const extensionIframe: HTMLIFrameElement = document.createElement('iframe'); extensionIframe.src = `${browser.runtime.getURL('interface/index.html')}#settings/embedded`; extensionIframe.id = 'ExtensionIframe'; - extensionIframe.allowTransparency = true; + extensionIframe.setAttribute('allowTransparency', 'true'); + extensionIframe.setAttribute('excludeDarkCheck', 'true'); extensionIframe.style.width = '384px'; extensionIframe.style.height = '600px'; extensionIframe.style.border = 'none'; - extensionIframe.setAttribute('excludeDarkCheck', true); extensionPopup.appendChild(extensionIframe); const container = document.getElementById('container'); const closeExtensionPopup = () => { + const ExtensionIframe = document.getElementById('ExtensionIframe') as HTMLIFrameElement; + extensionPopup.classList.add('hide'); animate( '#ExtensionPopup', { opacity: [1, 0], scale: [1, 0] }, { easing: [.22, .03, .26, 1] } ); - document.getElementById('ExtensionIframe').contentWindow.postMessage('popupClosed', '*'); + if (ExtensionIframe.contentWindow) { + ExtensionIframe.contentWindow.postMessage('popupClosed', '*'); + } SettingsClicked = false; }; - container.onclick = (event) => { - if (event.target.closest('#AddedSettings') == null && SettingsClicked) { + container!.onclick = (event) => { + if ((event.target as HTMLElement).closest('#AddedSettings') == null && SettingsClicked) { closeExtensionPopup() } }; } -function saveNewOrder(sortable) { +function saveNewOrder(sortable: any) { var order = sortable.toArray(); console.log("Order: ", order); browser.storage.local.set({ menuorder: order }); } -function cloneAttributes(target, source) { +function cloneAttributes(target: any, source: any) { [...source.attributes].forEach((attr) => { target.setAttribute(attr.nodeName, attr.nodeValue); }); @@ -910,26 +937,26 @@ function cloneAttributes(target, source) { export function OpenMenuOptions() { const result = browser.storage.local.get() - function open (result) { + function open (result: any) { var container = document.getElementById('container'); var menu = document.getElementById('menu'); if (result.defaultmenuorder.length == '0') { - let childnodes = menu.firstChild.childNodes; + let childnodes = menu!.firstChild!.childNodes; let newdefaultmenuorder = []; for (let i = 0; i < childnodes.length; i++) { const element = childnodes[i]; - newdefaultmenuorder.push(element.dataset.key); + newdefaultmenuorder.push((element as HTMLElement).dataset.key); browser.storage.local.set({ defaultmenuorder: newdefaultmenuorder }); } } - let childnodes = menu.firstChild.childNodes; + let childnodes = menu!.firstChild!.childNodes; if (result.defaultmenuorder.length != childnodes.length) { for (let i = 0; i < childnodes.length; i++) { const element = childnodes[i]; - if (!result.defaultmenuorder.indexOf(element.dataset.key)) { + if (!result.defaultmenuorder.indexOf((element as HTMLElement).dataset.key)) { let newdefaultmenuorder = result.defaultmenuorder; - newdefaultmenuorder.push(element.dataset.key); + newdefaultmenuorder.push((element as HTMLElement).dataset.key); browser.storage.local.set({ defaultmenuorder: newdefaultmenuorder }); } } @@ -939,9 +966,9 @@ export function OpenMenuOptions() { let cover = document.createElement('div'); cover.classList.add('notMenuCover'); - menu.style.zIndex = '20'; - menu.style.setProperty('--menuHidden', 'flex'); - container.append(cover); + menu!.style.zIndex = '20'; + menu!.style.setProperty('--menuHidden', 'flex'); + container!.append(cover); let menusettings = document.createElement('div'); menusettings.classList.add('editmenuoption-container'); @@ -959,66 +986,65 @@ export function OpenMenuOptions() { menusettings.appendChild(defaultbutton); menusettings.appendChild(savebutton); - menu.appendChild(menusettings); + menu!.appendChild(menusettings); - let ListItems = menu.firstChild.childNodes; + let ListItems = menu!.firstChild!.childNodes; for (let i = 0; i < ListItems.length; i++) { - const element = ListItems[i]; + const element1 = ListItems[i]; + const element = element1 as HTMLElement - element.classList.add('draggable'); - if (element.classList.contains('hasChildren')) { - element.classList.remove('active'); - menu.firstChild.classList.remove('noscroll'); + (element as HTMLElement).classList.add('draggable'); + if ((element as HTMLElement).classList.contains('hasChildren')) { + (element as HTMLElement).classList.remove('active'); + (element.firstChild as HTMLElement).classList.remove('noscroll'); } let MenuItemToggle = stringToHTML( - `
`, + `
`, ).firstChild; - element.append(MenuItemToggle); + (element as HTMLElement).append(MenuItemToggle!); if (!element.dataset.betterseqta) { const a = document.createElement('section') a.innerHTML = element.innerHTML cloneAttributes(a, element) - menu.firstChild.insertBefore(a, element) + menu!.firstChild!.insertBefore(a, element) element.remove() } } if (Object.keys(result.menuitems).length == 0) { - menubuttons = menu.firstChild.childNodes; + menubuttons = menu!.firstChild!.childNodes; var menuItems = {}; for (var i = 0; i < menubuttons.length; i++) { - var id = menubuttons[i].dataset.key; - const element = {}; + var id = (menubuttons[i] as HTMLElement).dataset.key; + const element: any = {}; element.toggle = true; - menuItems[id] = element; + (menuItems[id as keyof typeof menuItems] as any) = element; } browser.storage.local.set({ menuitems: menuItems }); } - var menubuttons = document.getElementsByClassName('menuitem'); + var menubuttons: any = document.getElementsByClassName('menuitem'); const result1 = browser.storage.local.get(['menuitems']) - function open (result) { + function open (result: any) { var menuItems = result.menuitems; let buttons = document.getElementsByClassName('menuitem'); for (var i = 0; i < buttons.length; i++) { var id = buttons[i].id; if (menuItems[id]) { - buttons[i].checked = menuItems[id].toggle; + (buttons[i] as HTMLInputElement).checked = menuItems[id].toggle; } if (!menuItems[id]) { - buttons[i].checked = true; + (buttons[i] as HTMLInputElement).checked = true; } } } result1.then(open, onError); - try { - Sortable.mount(new AutoScroll()); - + try { var el = document.querySelector('#menu > ul'); - var sortable = Sortable.create(el, { + var sortable = Sortable.create((el as HTMLElement), { draggable: '.draggable', dataIdAttr: 'data-key', animation: 150, @@ -1031,7 +1057,7 @@ export function OpenMenuOptions() { console.log(err); } - function changeDisplayProperty(element) { + function changeDisplayProperty(element: any) { if (!element.checked) { element.parentNode.parentNode.style.display = 'var(--menuHidden)'; } @@ -1045,15 +1071,15 @@ export function OpenMenuOptions() { } function StoreMenuSettings() { - const menuItems = {} - const menubuttons = menu.firstChild.childNodes + const menuItems: any = {}; + const menubuttons = menu!.firstChild!.childNodes const button = document.getElementsByClassName('menuitem') for (let i = 0; i < menubuttons.length; i++) { - const id = menubuttons[i].dataset.key - const element = {} - element.toggle = button[i].checked + const id = (menubuttons[i] as HTMLElement).dataset.key; + const element: any = {}; + element.toggle = (button[i] as HTMLInputElement).checked - menuItems[id] = element + menuItems[id as keyof typeof menuItems] = element; } browser.storage.local.set({ menuitems: menuItems }) } @@ -1069,28 +1095,29 @@ export function OpenMenuOptions() { function closeAll() { console.log("Closing!"); - ListItems = menu.firstChild.childNodes; + ListItems = menu!.firstChild!.childNodes; menusettings.remove(); cover.remove(); MenuOptionsOpen = false; - menu.style.setProperty('--menuHidden', 'none'); + menu!.style.setProperty('--menuHidden', 'none'); for (let i = 0; i < ListItems.length; i++) { - const element = ListItems[i]; + const element1 = ListItems[i]; + const element = element1 as HTMLElement element.classList.remove('draggable'); - element.setAttribute('draggable', false); + element.setAttribute('draggable', 'false'); if (!element.dataset.betterseqta) { const a = document.createElement('li') a.innerHTML = element.innerHTML cloneAttributes(a, element) - menu.firstChild.insertBefore(a, element) + menu!.firstChild!.insertBefore(a, element) element.remove() } } - let switches = menu.querySelectorAll('.onoffswitch'); + let switches = menu!.querySelectorAll('.onoffswitch'); for (let i = 0; i < switches.length; i++) { switches[i].remove(); } @@ -1102,7 +1129,7 @@ export function OpenMenuOptions() { defaultbutton.addEventListener('click', function () { const result = browser.storage.local.get() - function open (response) { + function open (response: any) { const options = response.defaultmenuorder; browser.storage.local.set({ menuorder: options }); ChangeMenuItemPositions(options); @@ -1124,33 +1151,33 @@ export function OpenMenuOptions() { result.then(open, onError) } -function ReplaceMenuSVG(element, svg) { - let item = element.firstChild; - item.firstChild.remove(); +function ReplaceMenuSVG(element: HTMLElement, svg: string) { + let item = element.firstChild as HTMLElement; + item!.firstChild!.remove(); if (element.dataset.key == 'messages') { - element.firstChild.innerText = 'Direct Messages'; + (element!.firstChild! as HTMLElement).innerText! = 'Direct Messages'; } let newsvg = stringToHTML(svg).firstChild; - item.insertBefore(newsvg, item.firstChild); + item.insertBefore((newsvg as Node), item.firstChild); } -async function AddBetterSEQTAElements(toggle) { - var code = document.getElementsByClassName('code')[0]; +async function AddBetterSEQTAElements(toggle: any) { + const code = document.getElementsByClassName('code')[0]; // Replaces students code with the version of BetterSEQTA if (code != null) { if (!code.innerHTML.includes('BetterSEQTA')) { - UserInitalCode = code.innerText; - code.innerText = `BetterSEQTA v${browser.runtime.getManifest().version}`; + UserInitalCode = code.innerHTML; + code.innerHTML = `BetterSEQTA v${browser.runtime.getManifest().version}`; code.setAttribute('data-hover', 'Click for user code'); code.addEventListener('click', function () { var code = document.getElementsByClassName('code')[0]; - if (code.innerText.includes('BetterSEQTA')) { - code.innerText = UserInitalCode; + if (code.innerHTML.includes('BetterSEQTA')) { + code.innerHTML = UserInitalCode; code.setAttribute('data-hover', 'Click for BetterSEQTA version'); } else { - code.innerText = `BetterSEQTA v${ + code.innerHTML = `BetterSEQTA v${ browser.runtime.getManifest().version }`; code.setAttribute('data-hover', 'Click for user code'); @@ -1159,106 +1186,110 @@ async function AddBetterSEQTAElements(toggle) { if (toggle) { // Creates Home menu button and appends it as the first child of the list - const result = browser.storage.local.get(['animatedbk']); - const sliderVal = browser.storage.local.get(['bksliderinput']); + const result = await browser.storage.local.get(); - result.then(animbkEnable); - sliderVal.then(updateBgDurations); + animbkEnable(result); + updateBgDurations(result); - // Load darkmode state - const result1 = browser.storage.local.get(['DarkMode']) - function open (result) { - DarkMode = result.DarkMode; + DarkMode = result.DarkMode; + if (DarkMode) { + document.documentElement.classList.add('dark'); } - result1.then(open, onError) - var titlebar = document.createElement('div'); - titlebar.classList.add('titlebar'); - let container = document.getElementById('content'); - container.append(titlebar); - var NewButtonStr = '
  • '; - var NewButton = stringToHTML(NewButtonStr); - var menu = document.getElementById('menu'); - var List = menu.firstChild; - List.insertBefore(NewButton.firstChild, List.firstChild); + const container = document.getElementById('content')!; + const div = document.createElement('div') + div.classList.add('titlebar'); + container.append(div); + const NewButton = stringToHTML('
  • '); - fetch(`${location.origin}/seqta/student/login`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json; charset=utf-8', - }, - body: JSON.stringify({ - mode: 'normal', - query: null, - redirect_url: location.origin, - }), - }) - .then((result) => result.json()) - .then((response) => { - let info = response.payload; + const menu = document.getElementById('menu')!; + const List = menu.firstChild! as HTMLElement; + + if (NewButton.firstChild) { + List.insertBefore(NewButton.firstChild, List.firstChild); + } - var titlebar = document.getElementsByClassName('titlebar')[0]; - titlebar.append( - stringToHTML( - '
    ', - ).firstChild, - ); - var userinfostr = `

    ${info.userDesc}

    ${UserInitalCode}

    `; - var userinfo = stringToHTML(userinfostr).firstChild; - - titlebar.append(userinfo); - - var logoutbutton = document.getElementsByClassName('logout')[0]; - var userInfosvgdiv = document.getElementById('logouttooltip'); - userInfosvgdiv.appendChild(logoutbutton); - - fetch(`${location.origin}/seqta/student/load/message/people`, { + try { + // Fetch the response and wait for it + const response = await fetch(`${location.origin}/seqta/student/login`, { method: 'POST', headers: { - 'Content-Type': 'application/json; charset=utf-8', + 'Content-Type': 'application/json; charset=utf-8', + }, + body: JSON.stringify({ + mode: 'normal', + query: null, + redirect_url: location.origin, + }), + }); + + // Parse the JSON response and wait for it + const responseData = await response.json(); + let info = responseData.payload; + + // Manipulate the DOM as needed + const titlebar = document.getElementsByClassName('titlebar')[0]; + const userInfo = stringToHTML( + '
    ', + ).firstChild; + titlebar.append(userInfo!); + + const userinfo = stringToHTML(`

    ${info.userDesc}

    ${UserInitalCode}

    `).firstChild; + titlebar.append(userinfo!); + + var logoutbutton = document.getElementsByClassName('logout')[0]; + var userInfosvgdiv = document.getElementById('logouttooltip')!; + userInfosvgdiv.appendChild(logoutbutton); + + } catch (error) { + console.error('Error fetching and processing data:', error); + } + + try { + // Await the fetch response + const response = await fetch(`${location.origin}/seqta/student/load/message/people`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json; charset=utf-8', }, body: JSON.stringify({ mode: 'student' }), - }) - .then((result) => result.json()) - .then((response) => { - let students = response.payload; - var index = students.findIndex(function (person) { - return ( - person.firstname == info.userDesc.split(' ')[0] && - person.surname == info.userDesc.split(' ')[1] - ); - }); - - let houseelement = - document.getElementsByClassName('userInfohouse')[0]; - if (students[index]?.house) { - houseelement.style.background = students[index].house_colour; - try { - let colorresult = GetThresholdOfColor( - students[index]?.house_colour, - ); - - if (colorresult && colorresult > 300) { - houseelement.style.color = 'black'; - } else if (colorresult < 300) { - houseelement.style.color = 'white'; - } else { - houseelement.style.color = 'black'; - } - houseelement.innerText = - students[index].year + students[index].house; - } catch (error) { - houseelement.innerText = students[index].house; - } - } else { - houseelement.innerText = students[index].year; - } - }); }); + + // Await the JSON parsing of the response + const responseData = await response.json(); + let students = responseData.payload; + + // Process the students data + var index = students.findIndex(function (person: any) { + return ( + person.firstname == students.userDesc.split(' ')[0] && + person.surname == students.userDesc.split(' ')[1] + ); + }); + + let houseelement1 = document.getElementsByClassName('userInfohouse')[0]; + const houseelement = houseelement1 as HTMLElement + if (students[index]?.house) { + (houseelement as HTMLElement).style.background = students[index].house_colour; + try { + let colorresult = GetThresholdOfColor(students[index]?.house_colour); + + houseelement.style.color = colorresult && colorresult > 300 ? 'black' : 'white'; + houseelement.innerText = students[index].year + students[index].house; + } catch (error) { + houseelement.innerText = students[index].house; + } + } else { + houseelement.innerText = students[index].year; + } + + } catch (error) { + console.error('Error fetching and processing student data:', error); + } var NewsButtonStr = '
  • '; var NewsButton = stringToHTML(NewsButtonStr); - List.appendChild(NewsButton.firstChild); + List!.appendChild(NewsButton.firstChild!); editmenu = document.createElement('div'); editmenu.classList.add('editmenu'); @@ -1266,33 +1297,33 @@ async function AddBetterSEQTAElements(toggle) { let svg = stringToHTML( '', ); - editmenu.append(svg.firstChild); + editmenu.append(svg.firstChild!); - menu.appendChild(editmenu); + menu!.appendChild(editmenu); let a = document.createElement('div'); a.classList.add('icon-cover'); a.id = 'icon-cover'; - menu.appendChild(a); + menu!.appendChild(a); var editmenu = document.querySelector('#editmenu'); - editmenu.addEventListener('click', function () { + editmenu!.addEventListener('click', function () { if (!MenuOptionsOpen) { OpenMenuOptions(); } }); var menuCover = document.querySelector('#icon-cover'); - menuCover.addEventListener('click', function () { + menuCover!.addEventListener('click', function () { location.href = '../#?page=/home'; SendHomePage(); - document - .getElementById('menu') - .firstChild.classList.remove('noscroll'); + (document! + .getElementById('menu')! + .firstChild! as HTMLElement).classList.remove('noscroll'); }); // Creates the home container when the menu button is pressed var homebutton = document.getElementById('homebutton'); - homebutton.addEventListener('click', function () { + homebutton!.addEventListener('click', function () { if (!MenuOptionsOpen) { SendHomePage(); } @@ -1300,7 +1331,7 @@ async function AddBetterSEQTAElements(toggle) { // Creates the news container when the menu button is pressed var newsbutton = document.getElementById('newsbutton'); - newsbutton.addEventListener('click', function () { + newsbutton!.addEventListener('click', function () { if (!MenuOptionsOpen) { SendNewsPage(); } @@ -1317,14 +1348,14 @@ async function AddBetterSEQTAElements(toggle) { '', ); var ContentDiv = document.getElementById('content'); - ContentDiv.append(SettingsButton.firstChild); + ContentDiv!.append(SettingsButton.firstChild!); - const result = await new Promise(resolve => { + const result: any = await new Promise(resolve => { const result = browser.storage.local.get(); result.then(resolve, onError) }); - const DarkMode = result.DarkMode; + const DarkMode = result!.DarkMode; const tooltipString = GetLightDarkModeString(DarkMode); const svgContent = DarkMode ? '' : ''; @@ -1336,34 +1367,34 @@ async function AddBetterSEQTAElements(toggle) { `); - ContentDiv.append(LightDarkModeButton.firstChild); + ContentDiv!.append(LightDarkModeButton.firstChild!); updateAllColors(DarkMode, result.selectedColor); - document.getElementById('LightDarkModeButton').addEventListener('click', async () => { - const result = await new Promise(resolve => { + document.getElementById('LightDarkModeButton')!.addEventListener('click', async () => { + const result: any = await new Promise(resolve => { const result = browser.storage.local.get(); result.then(resolve, onError) }); - const newDarkMode = !result.DarkMode; + const newDarkMode = !result!.DarkMode; browser.storage.local.set({ DarkMode: newDarkMode }); updateAllColors(newDarkMode, result.selectedColor); const darklightText = document.getElementById('darklighttooliptext'); - darklightText.innerText = GetLightDarkModeString(newDarkMode); + darklightText!.innerText = GetLightDarkModeString(newDarkMode); }); // Locate the menuToggle element const menuToggle = document.getElementById('menuToggle'); - menuToggle.innerHTML = ''; + menuToggle!.innerHTML = ''; // Create three divs to act as lines of the hamburger icon for (let i = 0; i < 3; i++) { const line = document.createElement('div'); line.className = 'hamburger-line'; - menuToggle.appendChild(line); + menuToggle!.appendChild(line); } } else { // Creates settings and dashboard buttons next to alerts @@ -1371,24 +1402,24 @@ async function AddBetterSEQTAElements(toggle) { '', ); ContentDiv = document.getElementById('content'); - ContentDiv.append(SettingsButton.firstChild); + ContentDiv!.append(SettingsButton.firstChild!); } var AddedSettings = document.getElementById('AddedSettings'); var extensionPopup = document.getElementById('ExtensionPopup'); - AddedSettings.addEventListener('click', function () { + AddedSettings!.addEventListener('click', function () { if (SettingsClicked) { - extensionPopup.classList.add('hide'); + extensionPopup!.classList.add('hide'); animate( '#ExtensionPopup', { opacity: [1, 0], scale: [1, 0] }, { easing: spring({ stiffness: 220, damping: 18 }) } ); - document.getElementById('ExtensionIframe').contentWindow.postMessage('popupClosed', '*'); + (document.getElementById('ExtensionIframe')! as HTMLIFrameElement).contentWindow!.postMessage('popupClosed', '*'); SettingsClicked = false; } else { - extensionPopup.classList.remove('hide'); + extensionPopup!.classList.remove('hide'); animate( '#ExtensionPopup', { opacity: [0, 1], scale: [0, 1] }, @@ -1403,7 +1434,7 @@ async function AddBetterSEQTAElements(toggle) { let tooltipstring; -function GetLightDarkModeString(darkmodetoggle) { +function GetLightDarkModeString(darkmodetoggle: boolean) { if (darkmodetoggle) { tooltipstring = 'Switch to light theme'; } else { @@ -1412,7 +1443,7 @@ function GetLightDarkModeString(darkmodetoggle) { return tooltipstring; } -function CheckCurrentLesson(lesson, num) { +function CheckCurrentLesson(lesson: any, num: number) { var startTime = lesson.from; var endTime = lesson.until; // Gets current time @@ -1422,13 +1453,13 @@ function CheckCurrentLesson(lesson, num) { let startDate = new Date(currentDate.getTime()); startDate.setHours(startTime.split(':')[0]); startDate.setMinutes(startTime.split(':')[1]); - startDate.setSeconds('00'); + startDate.setSeconds(parseInt('00')); // Takes end time of current lesson and makes it into a Date function for comparison let endDate = new Date(currentDate.getTime()); endDate.setHours(endTime.split(':')[0]); endDate.setMinutes(endTime.split(':')[1]); - endDate.setSeconds('00'); + endDate.setSeconds(parseInt('00')); // Gets the difference between the start time and current time var difference = startDate.getTime() - currentDate.getTime(); @@ -1464,7 +1495,7 @@ function CheckCurrentLesson(lesson, num) { // If 5 minutes before the start of another lesson: if (minutes == 5) { const result = browser.storage.local.get('lessonalert') - function open (result) { + function open (result: any) { if (result.lessonalert) { // Checks if notifications are supported if (!window.Notification) { @@ -1511,7 +1542,7 @@ function CheckCurrentLesson(lesson, num) { } } -export function GetThresholdOfColor(color) { +export function GetThresholdOfColor(color: any) { // Case-insensitive regular expression for matching RGBA colors const rgbaRegex = /rgba?\(([^)]+)\)/gi; @@ -1527,7 +1558,7 @@ export function GetThresholdOfColor(color) { const [r, g, b] = rgbaString.split(',').map(str => str.trim()); // Compute the threshold using your existing algorithm - const threshold = Math.sqrt(r ** 2 + g ** 2 + b ** 2); + const threshold = Math.sqrt(parseInt(r) ** 2 + parseInt(g) ** 2 + parseInt(b) ** 2); // Store the computed threshold gradientThresholds.push(threshold); @@ -1545,7 +1576,7 @@ export function GetThresholdOfColor(color) { } } -function CheckCurrentLessonAll(lessons) { +function CheckCurrentLessonAll(lessons: any) { // Checks each lesson and sets an interval to run every 60 seconds to continue updating LessonInterval = setInterval( function () { @@ -1558,13 +1589,13 @@ function CheckCurrentLessonAll(lessons) { } // Helper function to build the assessment URL -function buildAssessmentURL(programmeID, metaID, itemID = '') { +function buildAssessmentURL(programmeID: any, metaID: any, itemID = '') { const base = '../#?page=/assessments/'; return itemID ? `${base}${programmeID}:${metaID}&item=${itemID}` : `${base}${programmeID}:${metaID}`; } // Function to create a lesson div element from a lesson object -function makeLessonDiv(lesson, num) { +function makeLessonDiv(lesson: any, num: number) { if (!lesson) throw new Error('No lesson provided.'); const { code, colour, description, staff, room, from, until, attendanceTitle, programmeID, metaID, assessments } = lesson; @@ -1589,7 +1620,7 @@ function makeLessonDiv(lesson, num) { // Add assessments if they exist if (assessments && assessments.length > 0) { - const assessmentString = assessments.map(element => + const assessmentString = assessments.map((element: any) => `

    ${element.title}

    ` ).join(''); @@ -1608,7 +1639,7 @@ function makeLessonDiv(lesson, num) { return stringToHTML(lessonString); } -function CheckUnmarkedAttendance(lessonattendance) { +function CheckUnmarkedAttendance(lessonattendance: any) { if (lessonattendance) { var lesson = lessonattendance.label; } else { @@ -1617,7 +1648,7 @@ function CheckUnmarkedAttendance(lessonattendance) { return lesson; } -function callHomeTimetable(date, change) { +function callHomeTimetable(date: string, change?: any) { // Creates a HTTP Post Request to the SEQTA page for the students timetable var xhr = new XMLHttpRequest(); xhr.open('POST', `${location.origin}/seqta/student/load/timetable?`, true); @@ -1628,11 +1659,11 @@ function callHomeTimetable(date, change) { // Once the response is ready if (xhr.readyState === 4) { var serverResponse = JSON.parse(xhr.response); - let lessonArray = []; - var DayContainer = document.getElementById('day-container'); + let lessonArray: Array = []; + const DayContainer = document.getElementById('day-container')!; // If items in response: if (serverResponse.payload.items.length > 0) { - if (!DayContainer.innerText || change) { + if (DayContainer.innerText || change) { for (let i = 0; i < serverResponse.payload.items.length; i++) { lessonArray.push(serverResponse.payload.items[i]); } @@ -1647,7 +1678,7 @@ function callHomeTimetable(date, change) { let subjectname = `timetable.subject.colour.${lessonArray[i].code}`; let subject = subjects.find( - (element) => element.name === subjectname, + (element: any) => element.name === subjectname, ); if (!subject) { lessonArray[i].colour = '--item-colour: #8e8e8e;'; @@ -1674,10 +1705,11 @@ function callHomeTimetable(date, change) { var div = makeLessonDiv(lessonArray[i], i + 1); // Append each of the lessons into the day-container if (lessonArray[i].invert) { - div.firstChild.classList.add('day-inverted'); + const div1 = div.firstChild! as HTMLElement + div1.classList.add('day-inverted'); } - DayContainer.append(div.firstChild); + DayContainer.append(div.firstChild as HTMLElement); } const today = new Date(); @@ -1750,7 +1782,7 @@ async function GetActiveClasses() { } } -function comparedate(obj1, obj2) { +function comparedate(obj1: any, obj2: any) { if (obj1.date < obj2.date) { return -1; } @@ -1760,7 +1792,7 @@ function comparedate(obj1, obj2) { return 0; } -function CreateElement(type, class_, id, innerText, innerHTML, style) { +function CreateElement(type: string, class_?: any, id?: any, innerText?: string, innerHTML?: string, style?: string) { let element = document.createElement(type); if (class_ !== undefined) { element.classList.add(class_); @@ -1775,13 +1807,13 @@ function CreateElement(type, class_, id, innerText, innerHTML, style) { element.innerHTML = innerHTML; } if (style !== undefined) { - element.style = style; + element.style.cssText = style; } return element; } -function createAssessmentDateDiv(date, value, datecase = undefined) { - var options = { weekday: 'long', month: 'long', day: 'numeric' }; +function createAssessmentDateDiv(date: string, value: any, datecase?: any) { + var options = { weekday: 'long' as 'long', month: 'long' as 'long', day: 'numeric' as 'numeric' }; const FormattedDate = new Date(date); const assessments = value.assessments; @@ -1814,7 +1846,7 @@ function createAssessmentDateDiv(date, value, datecase = undefined) { item.setAttribute('data-subject', element.code); item.id = `assessment${element.id}`; - item.style = element.colour; + item.style.cssText = element.colour; let titlediv = document.createElement('div'); titlediv.classList.add('upcoming-subject-title'); @@ -1823,7 +1855,7 @@ function createAssessmentDateDiv(date, value, datecase = undefined) { stringToHTML(` `).firstChild; - titlediv.append(titlesvg); + titlediv.append(titlesvg!); let detailsdiv = document.createElement('div'); detailsdiv.classList.add('upcoming-details'); @@ -1833,7 +1865,7 @@ function createAssessmentDateDiv(date, value, datecase = undefined) { subject.innerText = element.title; subject.classList.add('upcoming-assessment-title'); subject.onclick = function () { - document.querySelector('#menu ul').classList.add('noscroll'); + document.querySelector('#menu ul')!.classList.add('noscroll'); location.href = `../#?page=/assessments/${element.programmeID}:${element.metaclassID}&item=${element.id}`; }; detailsdiv.append(detailstitle); @@ -1865,7 +1897,7 @@ function createAssessmentDateDiv(date, value, datecase = undefined) { let submittedtext = document.createElement('div'); submittedtext.classList.add('upcoming-submittedtext'); submittedtext.innerText = 'Submitted'; - assessment.append(submittedtext); + assessment!.append(submittedtext); } }); } @@ -1875,7 +1907,7 @@ function createAssessmentDateDiv(date, value, datecase = undefined) { return container; } -function CheckSpecialDay(date1, date2) { +function CheckSpecialDay(date1: Date, date2: Date) { if ( date1.getFullYear() === date2.getFullYear() && date1.getMonth() === date2.getMonth() && @@ -1899,24 +1931,25 @@ function CheckSpecialDay(date1, date2) { } } -function CreateSubjectFilter(subjectcode, itemcolour, checked) { +function CreateSubjectFilter(subjectcode: any, itemcolour: string, checked: any) { let label = CreateElement('label', 'upcoming-checkbox-container'); label.innerText = subjectcode; - let input = CreateElement('input'); + let input1 = CreateElement('input'); + const input = input1 as HTMLInputElement input.type = 'checkbox'; input.checked = checked; input.id = `filter-${subjectcode}`; - label.style = itemcolour; + label.style.cssText = itemcolour; let span = CreateElement('span', 'upcoming-checkmark'); label.append(input); label.append(span); input.addEventListener('change', function (change) { const result = browser.storage.local.get() - function open (storage) { + function open (storage: any) { let filters = storage.subjectfilters; - let id = change.target.id.split('-')[1]; - filters[id] = change.target.checked; + let id = (change.target as HTMLInputElement)!.id.split('-')[1]; + filters[id] = (change.target as HTMLInputElement)!.checked; browser.storage.local.set({ subjectfilters: filters }); } @@ -1926,9 +1959,9 @@ function CreateSubjectFilter(subjectcode, itemcolour, checked) { return label; } -function CreateFilters(subjects) { +function CreateFilters(subjects: any) { const result = browser.storage.local.get() - function open (result) { + function open (result: any) { let filteroptions = result.subjectfilters; let filterdiv = document.querySelector('#upcoming-filters'); @@ -1945,13 +1978,13 @@ function CreateFilters(subjects) { filteroptions[element.code], ); - filterdiv.append(elementdiv); + filterdiv!.append(elementdiv); } } result.then(open, onError) } -function CreateUpcomingSection(assessments) { +function CreateUpcomingSection(assessments: any, activeSubjects: any) { let upcomingitemcontainer = document.querySelector('#upcoming-items'); let overdueDates = []; let upcomingDates = {}; @@ -1984,7 +2017,7 @@ function CreateUpcomingSection(assessments) { for (let i = 0; i < assessments.length; i++) { let subjectname = `timetable.subject.colour.${assessments[i].code}`; - let subject = subjects.find((element) => element.name === subjectname); + let subject = subjects.find((element: any) => element.name === subjectname); if (!subject) { assessments[i].colour = '--item-colour: #8e8e8e;'; } else { @@ -1992,12 +2025,10 @@ function CreateUpcomingSection(assessments) { GetThresholdOfColor(subject.value); // result (originally) result = GetThresholdOfColor } } - - let activeSubjects = []; // TODO: IDK what is going on here, but it didn't exist for (let i = 0; i < activeSubjects.length; i++) { const element = activeSubjects[i]; let subjectname = `timetable.subject.colour.${element.code}`; - let colour = colours.find((element) => element.name === subjectname); + let colour = colours.find((element: any) => element.name === subjectname); if (!colour) { element.colour = '--item-colour: #8e8e8e;'; } else { @@ -2010,14 +2041,15 @@ function CreateUpcomingSection(assessments) { } CreateFilters(activeSubjects); - + // @ts-ignore let type; + // @ts-ignore let class_; for (let i = 0; i < assessments.length; i++) { - const element = assessments[i]; - if (!upcomingDates[element.due]) { - let dateObj = new Object(); + const element: any = assessments[i]; + if (!upcomingDates[element.due as keyof typeof upcomingDates]) { + let dateObj: any = new Object(); dateObj.div = CreateElement( // TODO: not sure whats going on here? // eslint-disable-next-line @@ -2027,48 +2059,48 @@ function CreateUpcomingSection(assessments) { ); dateObj.assessments = []; - upcomingDates[element.due] = dateObj; + dateObj = upcomingDates[element.due as keyof typeof upcomingDates] as any; } - let assessmentDateDiv = upcomingDates[element.due]; - assessmentDateDiv.assessments.push(element); + let assessmentDateDiv = upcomingDates[element.due as keyof typeof upcomingDates]; + (assessmentDateDiv as any).assessments.push(element); } for (var date in upcomingDates) { - let assessmentdue = new Date(upcomingDates[date].assessments[0].due); + let assessmentdue = new Date((upcomingDates[date as keyof typeof upcomingDates] as any).assessments[0].due); let specialcase = CheckSpecialDay(Today, assessmentdue); let assessmentDate; - let datecase; if (specialcase) { + let datecase: string = specialcase!; assessmentDate = createAssessmentDateDiv( date, - upcomingDates[date], + upcomingDates[date as keyof typeof upcomingDates], // eslint-disable-next-line - datecase = specialcase, + datecase, ); } else { - assessmentDate = createAssessmentDateDiv(date, upcomingDates[date]); + assessmentDate = createAssessmentDateDiv(date, upcomingDates[date as keyof typeof upcomingDates]); } if (specialcase === 'Yesterday') { - upcomingitemcontainer.insertBefore( + upcomingitemcontainer!.insertBefore( assessmentDate, - upcomingitemcontainer.firstChild, + upcomingitemcontainer!.firstChild, ); } else { - upcomingitemcontainer.append(assessmentDate); + upcomingitemcontainer!.append(assessmentDate); } } const result = browser.storage.local.get() - function open (result) { + function open (result: any) { FilterUpcomingAssessments(result.subjectfilters); } result.then(open, onError) }); } -function AddPlaceHolderToParent(parent, numberofassessments) { +function AddPlaceHolderToParent(parent: any, numberofassessments: any) { let textcontainer = CreateElement('div', 'upcoming-blank'); let textblank = CreateElement('p', 'upcoming-hiddenassessment'); let s = ''; @@ -2077,12 +2109,12 @@ function AddPlaceHolderToParent(parent, numberofassessments) { } textblank.innerText = `${numberofassessments} hidden assessment${s} due`; textcontainer.append(textblank); - textcontainer.setAttribute('data-hidden', true); + textcontainer.setAttribute('data-hidden', 'true'); parent.append(textcontainer); } -function FilterUpcomingAssessments(subjectoptions) { +function FilterUpcomingAssessments(subjectoptions: any) { for (var item in subjectoptions) { let subjectdivs = document.querySelectorAll(`[data-subject="${item}"]`); @@ -2095,9 +2127,9 @@ function FilterUpcomingAssessments(subjectoptions) { if (subjectoptions[item]) { element.classList.remove('hidden'); } - element.parentNode.classList.remove('hidden'); + (element.parentNode! as HTMLElement).classList.remove('hidden'); - let children = element.parentNode.parentNode.children; + let children = element.parentNode!.parentNode!.children; for (let i = 0; i < children.length; i++) { const element = children[i]; if (element.hasAttribute('data-hidden')) { @@ -2106,21 +2138,21 @@ function FilterUpcomingAssessments(subjectoptions) { } if ( - element.parentNode.children.length == - element.parentNode.querySelectorAll('.hidden').length + element.parentNode!.children.length == + element.parentNode!.querySelectorAll('.hidden').length ) { - if (element.parentNode.querySelectorAll('.hidden').length > 0) { - if (!element.parentNode.parentNode.hasAttribute('data-day')) { - element.parentNode.parentNode.classList.add('hidden'); + if (element.parentNode!.querySelectorAll('.hidden').length > 0) { + if (!(element.parentNode!.parentNode! as HTMLElement).hasAttribute('data-day')) { + (element.parentNode!.parentNode! as HTMLElement).classList.add('hidden'); } else { AddPlaceHolderToParent( - element.parentNode.parentNode, - element.parentNode.querySelectorAll('.hidden').length, + element.parentNode!.parentNode, + element.parentNode!.querySelectorAll('.hidden').length, ); } } } else { - element.parentNode.parentNode.classList.remove('hidden'); + (element.parentNode!.parentNode! as HTMLElement).classList.remove('hidden'); } } } @@ -2145,7 +2177,7 @@ async function GetLessonColours() { .then((response) => response.payload); } -export function CreateCustomShortcutDiv(element) { +export function CreateCustomShortcutDiv(element: any) { // Creates the stucture and element information for each seperate shortcut var shortcut = document.createElement('a'); shortcut.setAttribute('href', element.url); @@ -2171,18 +2203,18 @@ export function CreateCustomShortcutDiv(element) { `, ).firstChild; - image.classList.add('shortcuticondiv'); + (image as HTMLElement).classList.add('shortcuticondiv'); var text = document.createElement('p'); text.textContent = element.name; - shortcutdiv.append(image); + shortcutdiv.append(image!); shortcutdiv.append(text); shortcut.append(shortcutdiv); - document.getElementById('shortcuts').append(shortcut); + document.getElementById('shortcuts')!.append(shortcut); } -export function RemoveShortcutDiv(elements) { - elements.forEach((element) => { +export function RemoveShortcutDiv(elements: any) { + elements.forEach((element: any) => { const shortcuts = document.querySelectorAll('.shortcut'); shortcuts.forEach((shortcut) => { const anchorElement = shortcut.parentElement; // the element is the parent @@ -2193,11 +2225,11 @@ export function RemoveShortcutDiv(elements) { // Check href only if element.url exists if (element.url) { - shouldRemove = shouldRemove && (anchorElement.getAttribute('href') === element.url); + shouldRemove = shouldRemove && (anchorElement!.getAttribute('href') === element.url); } if (shouldRemove) { - anchorElement.remove(); + anchorElement!.remove(); } }); }); @@ -2205,11 +2237,11 @@ export function RemoveShortcutDiv(elements) { function AddCustomShortcutsToPage() { const result = browser.storage.local.get(['customshortcuts']) - function open (result) { + function open (result: any) { - var customshortcuts = Object.values(result)[0]; + var customshortcuts: any = Object.values(result)[0]; if (customshortcuts.length > 0) { - document.getElementsByClassName('shortcut-container')[0].style.display = + (document.getElementsByClassName('shortcut-container')[0] as HTMLElement).style.display = 'block'; for (let i = 0; i < customshortcuts.length; i++) { const element = customshortcuts[i]; @@ -2228,15 +2260,15 @@ function SendHomePage() { var element = document.querySelector('[data-key=home]'); // Apply the active class to indicate clicked on home button - element.classList.add('active'); + element!.classList.add('active'); // Remove all current elements in the main div to add new elements var main = document.getElementById('main'); - main.innerHTML = ''; + main!.innerHTML = ''; - const titlediv = document.getElementById('title').firstChild; - titlediv.innerText = 'Home'; - document.querySelector('link[rel*="icon"]').href = + const titlediv = document.getElementById('title')!.firstChild; + ((titlediv!) as HTMLElement).innerText = 'Home'; + (document.querySelector('link[rel*="icon"]')! as HTMLLinkElement).href = browser.runtime.getURL('icons/icon-48.png'); currentSelectedDate = new Date(); @@ -2246,7 +2278,7 @@ function SendHomePage() { // Appends the html file to main div // Note : firstChild of html is done due to needing to grab the body from the stringToHTML function - main.append(html.firstChild); + main!.append(html.firstChild!); // Gets the current date const date = new Date(); @@ -2262,13 +2294,14 @@ function SendHomePage() { var ShortcutStr = '
    '; var Shortcut = stringToHTML(ShortcutStr); // Appends the shortcut container into the home container - document.getElementById('home-container').append(Shortcut.firstChild); + document.getElementById('home-container')!.append(Shortcut.firstChild!); // Creates the container div for the timetable portion of the home page var TimetableStr = '

    Today\'s Lessons

    '; var Timetable = stringToHTML(TimetableStr); // Appends the timetable container into the home container - document.getElementById('home-container').append(Timetable.firstChild); + document.getElementById('home-container')!.append(Timetable.firstChild!); + callHomeTimetable(TodayFormatted, true) var timetablearrowback = document.getElementById('home-timetable-back'); var timetablearrowforward = document.getElementById( @@ -2279,35 +2312,35 @@ function SendHomePage() { var homelessonsubtitle = document.getElementById('home-lesson-subtitle'); const date = new Date(); if ( - date.getYear() == currentSelectedDate.getYear() && + date.getFullYear() == currentSelectedDate.getFullYear() && date.getMonth() == currentSelectedDate.getMonth() ) { if (date.getDate() == currentSelectedDate.getDate()) { // Change text to Today's Lessons - homelessonsubtitle.innerText = 'Today\'s Lessons'; + homelessonsubtitle!.innerText = 'Today\'s Lessons'; } else if (date.getDate() - 1 == currentSelectedDate.getDate()) { // Change text to Yesterday's Lessons - homelessonsubtitle.innerText = 'Yesterday\'s Lessons'; + homelessonsubtitle!.innerText = 'Yesterday\'s Lessons'; } else if (date.getDate() + 1 == currentSelectedDate.getDate()) { // Change text to Tomorrow's Lessons - homelessonsubtitle.innerText = 'Tomorrow\'s Lessons'; + homelessonsubtitle!.innerText = 'Tomorrow\'s Lessons'; } else { // Change text to date of the day - homelessonsubtitle.innerText = `${currentSelectedDate.toLocaleString( + homelessonsubtitle!.innerText = `${currentSelectedDate.toLocaleString( 'en-us', { weekday: 'short' }, )} ${currentSelectedDate.toLocaleDateString('en-au')}`; } } else { // Change text to date of the day - homelessonsubtitle.innerText = `${currentSelectedDate.toLocaleString( + homelessonsubtitle!.innerText = `${currentSelectedDate.toLocaleString( 'en-us', { weekday: 'short' }, )} ${currentSelectedDate.toLocaleDateString('en-au')}`; } } - function changeTimetable(value) { + function changeTimetable(value: any) { currentSelectedDate.setDate(currentSelectedDate.getDate() + value); let FormattedDate = currentSelectedDate.getFullYear() + @@ -2319,16 +2352,16 @@ function SendHomePage() { SetTimetableSubtitle(); } - timetablearrowback.addEventListener('click', function () { + timetablearrowback!.addEventListener('click', function () { changeTimetable(-1); }); - timetablearrowforward.addEventListener('click', function () { + timetablearrowforward!.addEventListener('click', function () { changeTimetable(1); }); // Adds the shortcuts to the shortcut container const result = browser.storage.local.get(['shortcuts']) - function open (result) { + function open (result: any) { const shortcuts = Object.values(result)[0]; addShortcuts(shortcuts); @@ -2361,7 +2394,7 @@ function SendHomePage() { upcomingcontainer.append(upcomingitems); - document.getElementById('home-container').append(upcomingcontainer); + document.getElementById('home-container')!.append(upcomingcontainer); // Creates the notices container into the home container const NoticesStr = String.raw` @@ -2375,7 +2408,7 @@ function SendHomePage() { var Notices = stringToHTML(NoticesStr); // Appends the shortcut container into the home container - document.getElementById('home-container').append(Notices.firstChild); + document.getElementById('home-container')!.append(Notices.firstChild!); animate( '.home-container > div', @@ -2403,18 +2436,18 @@ function SendHomePage() { const NoticesPayload = JSON.parse(xhr2.response) const NoticeContainer = document.getElementById('notice-container') if (NoticesPayload.payload.length === 0) { - if (!NoticeContainer.innerText) { + if (!NoticeContainer!.innerText) { // If no notices: display no notices const dummyNotice = document.createElement('div') dummyNotice.textContent = 'No notices for today.' dummyNotice.classList.add('dummynotice') - NoticeContainer.append(dummyNotice) + NoticeContainer!.append(dummyNotice) } } else { - if (!NoticeContainer.innerText) { + if (!NoticeContainer!.innerText) { // For each element in the response json: const result = browser.storage.local.get(['DarkMode']) - function noticeInfoDiv (result) { + function noticeInfoDiv (result: any) { for (let i = 0; i < NoticesPayload.payload.length; i++) { if (labelArray.includes(JSON.stringify(NoticesPayload.payload[i].label))) { // Create a div, and place information from json response @@ -2423,19 +2456,19 @@ function SendHomePage() { const title = stringToHTML( '

    ' + NoticesPayload.payload[i].title + '

    ' ) - NewNotice.append(title.firstChild) + NewNotice.append(title.firstChild!) if (NoticesPayload.payload[i].label_title !== undefined) { const label = stringToHTML( '
    ' + NoticesPayload.payload[i].label_title + '
    ' ) - NewNotice.append(label.firstChild) + NewNotice.append(label.firstChild!) } const staff = stringToHTML( '
    ' + NoticesPayload.payload[i].staff + '
    ' ) - NewNotice.append(staff.firstChild) + NewNotice.append(staff.firstChild!) // Converts the string into HTML const content = stringToHTML(NoticesPayload.payload[i].contents.replace(/\[\[[\w]+[:][\w]+[\]\]]+/g, '').replace(/ +/, ' '), true) for (let i = 0; i < content.childNodes.length; i++) { @@ -2455,11 +2488,11 @@ function SendHomePage() { const colourbar = document.createElement('div') colourbar.classList.add('colourbar') colourbar.style.background = 'var(--colour)' - NewNotice.style = `--colour: ${colour}` + NewNotice.style.cssText = `--colour: ${colour}` // Appends the colour bar to the new notice NewNotice.append(colourbar) // Appends the new notice into the notice container - NoticeContainer.append(NewNotice) + NoticeContainer!.append(NewNotice) } } } @@ -2469,9 +2502,9 @@ function SendHomePage() { } } // Data sent as the POST request - const dateControl = document.querySelector('input[type="date"]') - xhr2.send(JSON.stringify({ date: dateControl.value })) - function onInputChange (e) { + const dateControl = document.querySelector('input[type="date"]') as HTMLInputElement + xhr2.send(JSON.stringify({ date: dateControl!.value })) + function onInputChange (e: any) { xhr2.open('POST', `${location.origin}/seqta/student/load/notices?`, true) xhr2.setRequestHeader('Content-Type', 'application/json; charset=utf-8') xhr2.send(JSON.stringify({ date: e.target.value })) @@ -2480,18 +2513,18 @@ function SendHomePage() { const NoticesPayload = JSON.parse(xhr2.response) const NoticeContainer = document.getElementById('notice-container') if (NoticesPayload.payload.length === 0) { - if (!NoticeContainer.innerText) { + if (!NoticeContainer!.innerText) { // If no notices: display no notices const dummyNotice = document.createElement('div') dummyNotice.textContent = 'No notices for today.' dummyNotice.classList.add('dummynotice') - NoticeContainer.append(dummyNotice) + NoticeContainer!.append(dummyNotice) } } else { document.querySelectorAll('.notice').forEach(e => e.remove()) // For each element in the response json: const result = browser.storage.local.get(['DarkMode']) - function noticeInfoDiv (result) { + function noticeInfoDiv (result: any) { for (let i = 0; i < NoticesPayload.payload.length; i++) { if (labelArray.includes(JSON.stringify(NoticesPayload.payload[i].label))) { @@ -2501,19 +2534,19 @@ function SendHomePage() { const title = stringToHTML( '

    ' + NoticesPayload.payload[i].title + '

    ' ) - NewNotice.append(title.firstChild) + NewNotice.append(title.firstChild!) if (NoticesPayload.payload[i].label_title !== undefined) { const label = stringToHTML( '
    ' + NoticesPayload.payload[i].label_title + '
    ' ) - NewNotice.append(label.firstChild) + NewNotice.append(label.firstChild!) } const staff = stringToHTML( '
    ' + NoticesPayload.payload[i].staff + '
    ' ) - NewNotice.append(staff.firstChild) + NewNotice.append(staff.firstChild!) // Converts the string into HTML const content = stringToHTML(NoticesPayload.payload[i].contents.replace(/\[\[[\w]+[:][\w]+[\]\]]+/g, '').replace(/ +/, ' '), true) for (let i = 0; i < content.childNodes.length; i++) { @@ -2533,11 +2566,11 @@ function SendHomePage() { const colourbar = document.createElement('div') colourbar.classList.add('colourbar') colourbar.style.background = 'var(--colour)' - NewNotice.style = `--colour: ${colour}` + NewNotice.style.cssText = `--colour: ${colour}` // Appends the colour bar to the new notice NewNotice.append(colourbar) // Appends the new notice into the notice container - NoticeContainer.append(NewNotice) + NoticeContainer!.append(NewNotice) } } } @@ -2550,13 +2583,13 @@ function SendHomePage() { // Sends similar HTTP Post Request for the notices const result1 = browser.storage.local.get() - function open1 (result) { + function open1 (result: any) { if (result.notificationcollector) { enableNotificationCollector(); } } result1.then(open1, onError) - let activeClassList; + let activeClassList: any; GetUpcomingAssessments().then((assessments) => { GetActiveClasses().then((classes) => { // Gets all subjects for the student @@ -2594,14 +2627,14 @@ function SendHomePage() { }, 8); } -export function addShortcuts(shortcuts) { +export function addShortcuts(shortcuts: any) { for (let i = 0; i < shortcuts.length; i++) { const currentShortcut = shortcuts[i]; if (currentShortcut?.enabled) { const Itemname = (currentShortcut?.name ?? '').replace(/\s/g, ''); - const linkDetails = ShortcutLinks?.[Itemname]; + const linkDetails = ShortcutLinks?.[Itemname as keyof typeof ShortcutLinks]; if (linkDetails) { createNewShortcut( linkDetails.link, @@ -2648,16 +2681,16 @@ export function enableNotificationCollector() { export function disableNotificationCollector() { var alertdiv = document.getElementsByClassName('notifications__bubble___1EkSQ')[0]; if (typeof alertdiv != 'undefined') { - var currentNumber = parseInt(alertdiv.textContent); + var currentNumber = parseInt(alertdiv.textContent!); if (currentNumber < 9) { - alertdiv.textContent = currentNumber; + alertdiv.textContent = currentNumber.toString(); } else { alertdiv.textContent = '9+'; } } } -function createNewShortcut(link, icon, viewBox, title) { +function createNewShortcut(link: any, icon: any, viewBox: any, title: any) { // Creates the stucture and element information for each seperate shortcut let shortcut = document.createElement('a'); shortcut.setAttribute('href', link); @@ -2668,14 +2701,14 @@ function createNewShortcut(link, icon, viewBox, title) { let image = stringToHTML( ``, ).firstChild; - image.classList.add('shortcuticondiv'); + (image! as HTMLElement).classList.add('shortcuticondiv'); let text = document.createElement('p'); text.textContent = title; - shortcutdiv.append(image); + shortcutdiv.append(image as HTMLElement); shortcutdiv.append(text); shortcut.append(shortcutdiv); - document.getElementById('shortcuts').appendChild(shortcut); + document.getElementById('shortcuts')!.appendChild(shortcut); } function SendNewsPage() { @@ -2686,11 +2719,11 @@ function SendNewsPage() { var element = document.querySelector('[data-key=news]'); // Apply the active class to indicate clicked on home button - element.classList.add('active'); + element!.classList.add('active'); // Remove all current elements in the main div to add new elements var main = document.getElementById('main'); - main.innerHTML = ''; + main!.innerHTML = ''; // Creates the root of the home page added to the main div var htmlStr = '

    Latest Headlines - ABC News

    '; @@ -2698,16 +2731,16 @@ function SendNewsPage() { var html = stringToHTML(htmlStr); // Appends the html file to main div // Note : firstChild of html is done due to needing to grab the body from the stringToHTML function - main.append(html.firstChild); + main!.append(html.firstChild!); - const titlediv = document.getElementById('title').firstChild; - titlediv.innerText = 'News'; + const titlediv = document.getElementById('title')!.firstChild; + (titlediv! as HTMLElement).innerText = 'News'; AppendLoadingSymbol('newsloading', '#news-container'); - browser.runtime.sendMessage({ type: 'sendNews' }, function (response) { + browser.runtime.sendMessage({ type: 'sendNews' }).then(function (response) { let newsarticles = response.news.articles; var newscontainer = document.querySelector('#news-container'); - document.getElementById('newsloading').remove(); + document.getElementById('newsloading')!.remove(); for (let i = 0; i < newsarticles.length; i++) { let newsarticle = document.createElement('a'); newsarticle.classList.add('NewsArticle'); @@ -2742,7 +2775,7 @@ function SendNewsPage() { newsarticle.append(articleimage); newsarticle.append(articletext); - newscontainer.append(newsarticle); + newscontainer!.append(newsarticle); } }); }, 8); @@ -2751,7 +2784,7 @@ function SendNewsPage() { async function CheckForMenuList() { if (!MenuItemMutation) { try { - if (document.getElementById('menu').firstChild) { + if (document.getElementById('menu')!.firstChild) { ObserveMenuItemPosition(); MenuItemMutation = true; } @@ -2763,7 +2796,7 @@ async function CheckForMenuList() { function documentTextColor () { const result = browser.storage.local.get(['DarkMode']) - function changeDocTextCol (result) { + function changeDocTextCol (result: any) { const Darkmode = result.DarkMode if (Darkmode) { const documentArray = document.querySelectorAll('td:not([class^="colourBar"]):not([class^="title"])') @@ -2800,7 +2833,7 @@ browser.storage.onChanged.addListener(documentTextColor) function LoadInit() { console.log('[BetterSEQTA] Started Init'); const result = browser.storage.local.get() - function open (result) { + function open (result: any) { if (result.onoff) { SendHomePage(); } diff --git a/src/background.js b/src/background.ts similarity index 87% rename from src/background.js rename to src/background.ts index b4c60fbc..a456f11a 100644 --- a/src/background.js +++ b/src/background.ts @@ -1,11 +1,11 @@ import browser from 'webextension-polyfill' -import { onError } from './seqta/utils/onError.js'; +import { onError } from './seqta/utils/onError'; export const openDB = () => { return new Promise((resolve, reject) => { const request = indexedDB.open('MyDatabase', 1); - request.onupgradeneeded = (event) => { + request.onupgradeneeded = (event: any) => { const db = event.target.result; db.createObjectStore('backgrounds', { keyPath: 'id' }); }; @@ -14,14 +14,14 @@ export const openDB = () => { resolve(request.result); }; - request.onerror = (event) => { + request.onerror = (event: any) => { reject('Error opening database: ' + event.target.errorCode); }; }); }; -export const writeData = async (type, data) => { - const db = await openDB(); +export const writeData = async (type: any, data: any) => { + const db: any = await openDB(); const tx = db.transaction('backgrounds', 'readwrite'); const store = tx.objectStore('backgrounds'); @@ -33,7 +33,7 @@ export const writeData = async (type, data) => { export const readData = () => { return new Promise((resolve, reject) => { openDB() - .then(db => { + .then((db: any) => { const tx = db.transaction('backgrounds', 'readonly'); const store = tx.objectStore('backgrounds'); @@ -41,11 +41,11 @@ export const readData = () => { const getRequest = store.get('customBackground'); // Attach success and error event handlers - getRequest.onsuccess = function(event) { + getRequest.onsuccess = function(event: any) { resolve(event.target.result); }; - getRequest.onerror = function(event) { + getRequest.onerror = function(event: any) { console.error('An error occurred:', event); reject(event); }; @@ -59,7 +59,7 @@ export const readData = () => { function reloadSeqtaPages() { const result = browser.tabs.query({}) - function open (tabs) { + function open (tabs: any) { for (let tab of tabs) { if (tab.title.includes('SEQTA Learn')) { browser.tabs.reload(tab.id); @@ -69,8 +69,10 @@ function reloadSeqtaPages() { result.then(open, onError) } +// Helper function to handle setting permissions + // Main message listener -browser.runtime.onMessage.addListener((request, sender, sendResponse) => { +browser.runtime.onMessage.addListener((request: any, _sender: any, sendResponse: any) => { switch (request.type) { case 'reloadTabs': reloadSeqtaPages(); @@ -78,7 +80,7 @@ browser.runtime.onMessage.addListener((request, sender, sendResponse) => { case 'currentTab': browser.tabs.query({ active: true, currentWindow: true }).then(function (tabs) { - browser.tabs.sendMessage(tabs[0].id, request).then(function (response) { + browser.tabs.sendMessage(tabs[0].id!, request).then(function (response) { sendResponse(response); }); }); @@ -101,7 +103,7 @@ browser.runtime.onMessage.addListener((request, sender, sendResponse) => { } }); -function GetNews(sendResponse) { +function GetNews(sendResponse: any) { // Gets the current date const date = new Date(); @@ -119,14 +121,14 @@ function GetNews(sendResponse) { .then((response) => { if (response.code == 'rateLimited') { url += '%00'; - GetNews(); + GetNews({}); } else { sendResponse({ news: response }); } }); } -const DefaultValues = { +const DefaultValues: any = { onoff: true, animatedbk: true, bksliderinput: 50, @@ -192,7 +194,7 @@ const DefaultValues = { customshortcuts: [], }; -function SetStorageValue(object) { +function SetStorageValue(object: any) { for (var i in object) { browser.storage.local.set({ [i]: object[i] }); } @@ -200,12 +202,12 @@ function SetStorageValue(object) { function UpdateCurrentValues() { const result = browser.storage.local.get() - function open (items) { + function open (items: any) { var CurrentValues = items; const NewValue = Object.assign({}, DefaultValues, CurrentValues); - function CheckInnerElement(element) { + function CheckInnerElement(element: any) { for (let i in element) { if (typeof element[i] === 'object') { if (typeof DefaultValues[i].length == 'undefined') { @@ -236,13 +238,13 @@ function UpdateCurrentValues() { function migrateOldStorage() { const result = browser.storage.local.get() - function open (items) { + function open (items: any) { let shouldUpdate = false; // Flag to check if there is anything to update // Check for the old "Name" field and convert it to "name" if (items.shortcuts && items.shortcuts.length > 0 && 'Name' in items.shortcuts[0]) { shouldUpdate = true; - items.shortcuts = items.shortcuts.map((shortcut) => { + items.shortcuts = items.shortcuts.map((shortcut: any) => { return { name: shortcut.Name, // Convert "Name" to "name" enabled: shortcut.enabled // Keep the "enabled" field as is diff --git a/src/seqta/icons/assessmentsIcon.js b/src/seqta/icons/assessmentsIcon.ts similarity index 100% rename from src/seqta/icons/assessmentsIcon.js rename to src/seqta/icons/assessmentsIcon.ts diff --git a/src/seqta/icons/coursesIcon.js b/src/seqta/icons/coursesIcon.ts similarity index 100% rename from src/seqta/icons/coursesIcon.js rename to src/seqta/icons/coursesIcon.ts diff --git a/src/seqta/ui/Animation.js b/src/seqta/ui/Animation.ts similarity index 77% rename from src/seqta/ui/Animation.js rename to src/seqta/ui/Animation.ts index 108ea20a..68227430 100644 --- a/src/seqta/ui/Animation.js +++ b/src/seqta/ui/Animation.ts @@ -4,10 +4,10 @@ * @param {number} [minDuration=1] - The minimum animation duration in seconds. * @param {number} [maxDuration=10] - The maximum animation duration in seconds. */ -export function updateBgDurations(speed, minDuration = 0.5, maxDuration = 10) { +export function updateBgDurations(speed: any, minDuration = 0.5, maxDuration = 10) { // Class names to look for const bgClasses = ['bg', 'bg2', 'bg3']; - let reversedValue; + let reversedValue: any; if (speed.bksliderinput === undefined) { // Reverse the slider direction to align with the animation @@ -20,7 +20,7 @@ export function updateBgDurations(speed, minDuration = 0.5, maxDuration = 10) { const durationRange = maxDuration - minDuration; // Function to calculate animation duration - const calcDuration = (baseValue, offset = 0) => minDuration + ((baseValue / 200) + offset) * durationRange; + const calcDuration = (baseValue: number, offset = 0) => minDuration + ((baseValue / 200) + offset) * durationRange; // Iterate through each class name to update its animation duration bgClasses.forEach((className, index) => { @@ -32,6 +32,6 @@ export function updateBgDurations(speed, minDuration = 0.5, maxDuration = 10) { const offset = index * 0.05; const duration = calcDuration(reversedValue, offset); - elements[0].style.animationDuration = `${duration}s`; + (elements[0] as HTMLElement).style.animationDuration = `${duration}s`; }); } \ No newline at end of file diff --git a/src/seqta/ui/ImageBackgrounds.js b/src/seqta/ui/ImageBackgrounds.ts similarity index 93% rename from src/seqta/ui/ImageBackgrounds.js rename to src/seqta/ui/ImageBackgrounds.ts index 53a4e3f0..15782c9a 100644 --- a/src/seqta/ui/ImageBackgrounds.js +++ b/src/seqta/ui/ImageBackgrounds.ts @@ -11,5 +11,5 @@ export async function appendBackgroundToUI() { background.classList.add('imageBackground'); background.setAttribute('excludeDarkCheck', 'true'); background.src = browser.runtime.getURL('backgrounds/background.html'); - parent.appendChild(background); + parent!.appendChild(background); } diff --git a/src/seqta/ui/Loading.js b/src/seqta/ui/Loading.ts similarity index 99% rename from src/seqta/ui/Loading.js rename to src/seqta/ui/Loading.ts index 7754af7d..fbac1fbe 100644 --- a/src/seqta/ui/Loading.js +++ b/src/seqta/ui/Loading.ts @@ -1,5 +1,5 @@ import browser from 'webextension-polyfill' -import stringToHTML from '../utils/stringToHTML.js'; +import stringToHTML from '../utils/stringToHTML'; const loadingSpinner = ` @@ -8,7 +8,7 @@ const loadingSpinner = ` `; -export function AppendLoadingSymbol(givenID, position) { +export function AppendLoadingSymbol(givenID: any, position: any) { let loadingsymbol = stringToHTML(String.raw`
    ${loadingSpinner} @@ -79,5 +79,5 @@ export default function loading() { }
    `, ); var html = document.getElementsByTagName('html')[0]; - html.append(loadinghtml.firstChild); + html.append(loadinghtml.firstChild!); } \ No newline at end of file diff --git a/src/seqta/ui/Themes.js b/src/seqta/ui/Themes.ts similarity index 82% rename from src/seqta/ui/Themes.js rename to src/seqta/ui/Themes.ts index 6c1d29f9..7762ded8 100644 --- a/src/seqta/ui/Themes.js +++ b/src/seqta/ui/Themes.ts @@ -4,31 +4,31 @@ import localforage from 'localforage'; let currentThemeClass = ''; // Utility function to fetch and parse JSON -const fetchJSON = async (url) => { +const fetchJSON = async (url: any) => { const res = await fetch(url, {cache: 'no-store'}); return await res.json(); }; // Utility function to fetch and parse text -const fetchText = async (url) => { +const fetchText = async (url: any) => { const res = await fetch(url); return await res.text(); }; // Check if the theme already exists in IndexedDB -const themeExistsInDB = async (themeName) => { +const themeExistsInDB = async (themeName: any) => { return (await localforage.getItem(`css_${themeName}`)) !== null; }; // Fetch theme details (CSS, images, className, darkMode, defaultColour) from a given URL -const fetchThemeJSON = async (url) => { +const fetchThemeJSON = async (url: any) => { const { css, images, className, darkMode, defaultColour } = await fetchJSON(url); const cssText = await fetchText(css); return { css: cssText, images, className, darkMode, defaultColour }; }; // Save individual image to IndexedDB -const saveImageToDB = async (themeName, cssVar, imageUrl) => { +const saveImageToDB = async (themeName: any, cssVar: any, imageUrl: any) => { try { const response = await fetch(imageUrl); if (!response.ok) throw new Error(response.statusText); @@ -40,14 +40,21 @@ const saveImageToDB = async (themeName, cssVar, imageUrl) => { }; // Save theme details to storage via localForage -const saveToIndexedDB = async (theme, themeName) => { +const saveToIndexedDB = async (theme: any, themeName: any) => { await localforage.setItem(`css_${themeName}`, theme); await Promise.all(Object.entries(theme.images).map(([cssVar, imageUrl]) => saveImageToDB(themeName, cssVar, imageUrl))); }; +declare global { + interface Window { + currentThemeStyle: any; + currentThemeClass: any; + } +} + // Apply theme from storage via localForage to document, including dark mode and default color -const applyTheme = async (themeName) => { - const { css, className, images, darkMode, defaultColour } = await localforage.getItem(`css_${themeName}`); +const applyTheme = async (themeName: any) => { + const { css, className, images, darkMode, defaultColour }: any = await localforage.getItem(`css_${themeName}`); const newStyle = document.createElement('style'); newStyle.innerHTML = css; @@ -70,7 +77,7 @@ const applyTheme = async (themeName) => { if (images) { await Promise.all( Object.keys(images).map(async (cssVar) => { - const imageData = await localforage.getItem(`images_${themeName}_${cssVar}`); + const imageData: any = await localforage.getItem(`images_${themeName}_${cssVar}`); const objectURL = URL.createObjectURL(imageData); document.documentElement.style.setProperty(cssVar, `url(${objectURL})`); }) @@ -88,13 +95,13 @@ export const listThemes = async () => { }; }; -export const downloadTheme = async (themeName, themeUrl) => { +export const downloadTheme = async (themeName: any, themeUrl: any) => { const themeData = await fetchThemeJSON(themeUrl); await saveToIndexedDB(themeData, themeName); await setTheme(themeName, themeUrl); }; -export const deleteTheme = async (themeName) => { +export const deleteTheme = async (themeName: any) => { const currentTheme = await localforage.getItem('selectedTheme'); if (currentTheme === themeName) { await disableTheme(); @@ -105,7 +112,7 @@ export const deleteTheme = async (themeName) => { ); }; -export const setTheme = async (themeName, themeUrl) => { +export const setTheme = async (themeName: any, themeUrl: any) => { if (!(await themeExistsInDB(themeName))) { await downloadTheme(themeName, themeUrl); } @@ -142,7 +149,7 @@ export const disableTheme = async () => { // Remove any applied image URLs from the root element const currentTheme = await localforage.getItem('selectedTheme'); if (currentTheme) { - const themeData = await localforage.getItem(`css_${currentTheme}`); + const themeData: any = await localforage.getItem(`css_${currentTheme}`); if (themeData && themeData.images) { Object.keys(themeData.images).forEach(cssVar => { document.documentElement.style.removeProperty(cssVar); diff --git a/src/seqta/ui/colors/ColorLuminance.js b/src/seqta/ui/colors/ColorLuminance.ts similarity index 83% rename from src/seqta/ui/colors/ColorLuminance.js rename to src/seqta/ui/colors/ColorLuminance.ts index 10c92764..2605f36d 100644 --- a/src/seqta/ui/colors/ColorLuminance.js +++ b/src/seqta/ui/colors/ColorLuminance.ts @@ -1,6 +1,6 @@ import Color from 'color'; -function adjustLuminance(color, lum) { +function adjustLuminance(color: any, lum: any) { let adjustedColor = Color(color.toLowerCase()); const rgbObj = adjustedColor.rgb().object(); @@ -14,7 +14,7 @@ function adjustLuminance(color, lum) { return adjustedColor.string(); } -export default function ColorLuminance(color, lum = 0) { +export default function ColorLuminance(color: any, lum = 0) { const colorRegex = /rgba?\(([^)]+)\)/gi; // Case-insensitive match for rgb() or rgba() if (color.toLowerCase().includes('gradient')) { @@ -31,7 +31,7 @@ export default function ColorLuminance(color, lum = 0) { // Adjust luminance for each unique color stop for (let colorStop of uniqueColorSet) { const adjustedColor = adjustLuminance(colorStop, lum); - gradient = gradient.replace(new RegExp(colorStop, 'gi'), adjustedColor); + gradient = gradient.replace(new RegExp(colorStop as string, 'gi'), adjustedColor); } return gradient; diff --git a/src/seqta/ui/colors/Manager.js b/src/seqta/ui/colors/Manager.ts similarity index 73% rename from src/seqta/ui/colors/Manager.js rename to src/seqta/ui/colors/Manager.ts index f64f6187..d5f57aee 100644 --- a/src/seqta/ui/colors/Manager.js +++ b/src/seqta/ui/colors/Manager.ts @@ -1,17 +1,17 @@ import browser from 'webextension-polyfill' -import { GetThresholdOfColor, GetCSSElement } from '../../../SEQTA.js'; -import { lightenAndPaleColor } from './lightenAndPaleColor.js'; -import ColorLuminance from './ColorLuminance.js'; -import { onError } from '../../utils/onError.js'; +import { GetThresholdOfColor, GetCSSElement } from '../../../SEQTA'; +import { lightenAndPaleColor } from './lightenAndPaleColor'; +import ColorLuminance from './ColorLuminance'; +import { onError } from '../../utils/onError'; // Helper functions -const setCSSVar = (varName, value) => document.documentElement.style.setProperty(varName, value); -const getChromeURL = (path) => browser.runtime.getURL(path); -const applyProperties = (props) => Object.entries(props).forEach(([key, value]) => setCSSVar(key, value)); +const setCSSVar = (varName: any, value: any) => document.documentElement.style.setProperty(varName, value); +const getChromeURL = (path: any) => browser.runtime.getURL(path); +const applyProperties = (props: any) => Object.entries(props).forEach(([key, value]) => setCSSVar(key, value)); -let DarkMode = null; +let DarkMode: any = null; -export function updateAllColors(storedSetting, newColor = null) { +export function updateAllColors(storedSetting: any, newColor = null) { // Determine the color to use const selectedColor = newColor || storedSetting.selectedColor; @@ -63,7 +63,7 @@ export function updateAllColors(storedSetting, newColor = null) { // Set favicon, if storedSetting is provided if (DarkMode !== null) { - document.querySelector('link[rel*=\'icon\']').href = getChromeURL('icons/icon-48.png'); + (document.querySelector('link[rel*=\'icon\']')! as HTMLLinkElement).href = getChromeURL('icons/icon-48.png'); } let alliframes = document.getElementsByTagName('iframe'); @@ -77,11 +77,11 @@ export function updateAllColors(storedSetting, newColor = null) { } console.log(element); - console.log(element.contentDocument.documentElement); + console.log(element.contentDocument!.documentElement); - element.contentDocument.documentElement.childNodes[1].style.color = + (element.contentDocument!.documentElement.childNodes[1] as HTMLIFrameElement).style.color = DarkMode ? 'white' : 'black'; - element.contentDocument.documentElement.firstChild.appendChild( + element.contentDocument!.documentElement.firstChild!.appendChild( fileref, ); } @@ -90,7 +90,7 @@ export function updateAllColors(storedSetting, newColor = null) { export function getDarkMode() { return new Promise((resolve, reject) => { const result = browser.storage.local.get('DarkMode') - function open (result) { + function open (result: any) { if (browser.runtime.lastError) { return reject(browser.runtime.lastError); } diff --git a/src/seqta/ui/colors/lightenAndPaleColor.js b/src/seqta/ui/colors/lightenAndPaleColor.ts similarity index 80% rename from src/seqta/ui/colors/lightenAndPaleColor.js rename to src/seqta/ui/colors/lightenAndPaleColor.ts index 2dc28709..34107ba8 100644 --- a/src/seqta/ui/colors/lightenAndPaleColor.js +++ b/src/seqta/ui/colors/lightenAndPaleColor.ts @@ -1,7 +1,7 @@ import Color from 'color'; -export function lightenAndPaleColor(inputColor, lightenFactor = 0.75, paleFactor = 0.55) { +export function lightenAndPaleColor(inputColor: any, lightenFactor = 0.75, paleFactor = 0.55) { if (inputColor.includes('gradient')) { const baseColor = findMatchingColor(inputColor); @@ -27,9 +27,9 @@ export function lightenAndPaleColor(inputColor, lightenFactor = 0.75, paleFactor return result; } // Utility function to average an array of Color objects -function averageColors(colors) { +function averageColors(colors: any) { let avgR = 0, avgG = 0, avgB = 0; - colors.forEach(color => { + colors.forEach((color: any) => { avgR += color.red(); avgG += color.green(); avgB += color.blue(); @@ -37,7 +37,7 @@ function averageColors(colors) { return Color.rgb(avgR / colors.length, avgG / colors.length, avgB / colors.length); } // Main function to find a matching color for a CSS gradient -function findMatchingColor(cssGradient) { +function findMatchingColor(cssGradient: any) { try { // Step 1: Parse the gradient to extract color stops (case-insensitive) const regex = /#[0-9a-fA-F]{6}|rgb\(\s*\d+\s*,\s*\d+\s*,\s*\d+\s*\)|rgba\(\s*\d+\s*,\s*\d+\s*,\s*\d+\s*,\s*[\d.]+\s*\)/gi; @@ -48,10 +48,10 @@ function findMatchingColor(cssGradient) { } // Normalize and trim the color stops - const normalizedColorStops = colorStops.map(color => color.toLowerCase().replace(/\s+/g, '')); + const normalizedColorStops = colorStops.map((color: any) => color.toLowerCase().replace(/\s+/g, '')); // Convert the color stops to Color objects - const colorObjects = normalizedColorStops.map(color => Color(color)); + const colorObjects = normalizedColorStops.map((color: any) => Color(color)); // Step 2: Average the color stops const baseColor = averageColors(colorObjects); @@ -59,7 +59,7 @@ function findMatchingColor(cssGradient) { // Step 4: Return the matching color in HEX format return baseColor.hex(); - } catch (err) { + } catch (err: any) { console.error(`Error: ${err.message}`); return null; } diff --git a/src/seqta/utils/FileUpload.js b/src/seqta/utils/FileUpload.ts similarity index 80% rename from src/seqta/utils/FileUpload.js rename to src/seqta/utils/FileUpload.ts index 59536648..d319f482 100644 --- a/src/seqta/utils/FileUpload.js +++ b/src/seqta/utils/FileUpload.ts @@ -1,11 +1,11 @@ /** * Uploads an image file to a specified endpoint using a POST request. * - * @param {File} file - The image file to be uploaded. + * @param {File} file - The file to be uploaded. * @returns {Promise} A promise that resolves to the response from the server. * @throws {Error} If no file is provided or if there is an error during upload. */ -export async function UploadImage(file) { +export async function UploadImage(file: File): Promise { // Ensuring that file is provided if (!file) { throw new Error("No file provided"); @@ -28,12 +28,12 @@ export async function UploadImage(file) { }; // Making the fetch request and returning the promise - return fetch('/seqta/student/file/upload/xhr2', requestOptions) - .then(response => { + return await fetch('/seqta/student/file/upload/xhr2', requestOptions) + .then(async response => { if (!response.ok) { throw new Error(`HTTP error! Status: ${response.status}`); } - const json = response.json(); + const json = await response.json(); return `/seqta/student/load/file?type=message&file=${json.uuid}`; }) .catch(error => { diff --git a/src/seqta/utils/GetPrefs.js b/src/seqta/utils/GetPrefs.ts similarity index 100% rename from src/seqta/utils/GetPrefs.js rename to src/seqta/utils/GetPrefs.ts diff --git a/src/seqta/utils/MessageListener.js b/src/seqta/utils/MessageListener.ts similarity index 68% rename from src/seqta/utils/MessageListener.js rename to src/seqta/utils/MessageListener.ts index 407e6018..aa6d3c66 100644 --- a/src/seqta/utils/MessageListener.js +++ b/src/seqta/utils/MessageListener.ts @@ -1,14 +1,13 @@ import browser from 'webextension-polyfill' -import { MenuOptionsOpen, OpenMenuOptions, closeSettings } from '../../SEQTA.js'; -import { deleteTheme, disableTheme, downloadTheme, listThemes, setTheme } from '../ui/Themes.js'; +import { MenuOptionsOpen, OpenMenuOptions, closeSettings } from '../../SEQTA'; +import { deleteTheme, disableTheme, downloadTheme, listThemes, setTheme } from '../ui/Themes'; export class MessageHandler { constructor() { browser.runtime.onMessage.addListener(this.routeMessage.bind(this)); } - - routeMessage(request, sender, sendResponse) { + routeMessage(request: any, _sender: any, sendResponse: any) { switch (request.info) { case 'EditSidebar': @@ -56,23 +55,4 @@ export class MessageHandler { closeSettings(); } } - - // Add more methods for handling other message types -} - -/* // Apply theme from the message -async function applyThemeFromMessage(themeData) { - const style = document.createElement("style"); - style.innerHTML = themeData.css; - document.head.appendChild(style); - - document.body.className = themeData.className; - - if (themeData.images) { - for (const [cssVar, objectURL] of Object.entries(themeData.images)) { - document.documentElement.style.setProperty(cssVar, `url(${objectURL})`); - } - } else { - console.error("themeData.images is not defined!"); - } -} */ \ No newline at end of file +} \ No newline at end of file diff --git a/src/seqta/utils/StorageListener.js b/src/seqta/utils/StorageListener.ts similarity index 81% rename from src/seqta/utils/StorageListener.js rename to src/seqta/utils/StorageListener.ts index 9ff02897..48b07709 100644 --- a/src/seqta/utils/StorageListener.js +++ b/src/seqta/utils/StorageListener.ts @@ -8,17 +8,19 @@ import { addShortcuts, disableNotificationCollector, enableNotificationCollector, -} from '../../SEQTA.js'; -import { updateBgDurations } from '../ui/Animation.js'; -import { getDarkMode, updateAllColors } from '../ui/colors/Manager.js'; +} from '../../SEQTA'; +import { updateBgDurations } from '../ui/Animation'; +import { getDarkMode, updateAllColors } from '../ui/colors/Manager'; + export default class StorageListener { + darkMode: any; constructor() { this.darkMode = getDarkMode(); browser.storage.onChanged.addListener(this.handleStorageChanges.bind(this)); } - handleStorageChanges(changes) { + handleStorageChanges(changes: any) { Object.keys(changes).forEach((changeKey) => { switch (changeKey) { @@ -60,7 +62,7 @@ export default class StorageListener { CreateBackground(); } else { RemoveBackground(); - document.getElementById('container').style.background = 'var(--background-secondary)'; + document.getElementById('container')!.style.background = 'var(--background-secondary)'; } break; @@ -80,7 +82,7 @@ export default class StorageListener { }); } - handleSelectedColorChange(newColor) { + handleSelectedColorChange(newColor: any) { try { updateAllColors(this.darkMode, newColor); } catch (err) { @@ -88,7 +90,7 @@ export default class StorageListener { } } - handleNotificationCollectorChange(details) { + handleNotificationCollectorChange(details: any) { if (details.newValue) { enableNotificationCollector(); } else { @@ -96,7 +98,7 @@ export default class StorageListener { } } - handleCustomShortcutsChange(oldValue, newValue) { + handleCustomShortcutsChange(oldValue: any, newValue: any) { // Check for addition if (newValue.length > oldValue.length) { CreateCustomShortcutDiv(newValue[oldValue.length]); @@ -104,9 +106,9 @@ export default class StorageListener { // Check for removal else if (newValue.length < oldValue.length) { const removedElement = oldValue.find( - (oldItem) => + (oldItem: any) => !newValue.some( - (newItem) => JSON.stringify(oldItem) === JSON.stringify(newItem) + (newItem: any) => JSON.stringify(oldItem) === JSON.stringify(newItem) ) ); @@ -116,10 +118,10 @@ export default class StorageListener { } } - handleShortcutsChange(oldValue, newValue) { + handleShortcutsChange(oldValue: any, newValue: any) { // Find Added Shortcuts - const addedShortcuts = newValue.filter(newItem => { - const isAdded = oldValue.some(oldItem => { + const addedShortcuts = newValue.filter((newItem: any) => { + const isAdded = oldValue.some((oldItem: any) => { const match = oldItem.name === newItem.name; const wasDisabled = !oldItem.enabled; const isEnabled = newItem.enabled; @@ -130,8 +132,8 @@ export default class StorageListener { }); // Find Removed Shortcuts - const removedShortcuts = newValue.filter(newItem => { - const isRemoved = oldValue.some(oldItem => { + const removedShortcuts = newValue.filter((newItem: any) => { + const isRemoved = oldValue.some((oldItem: any) => { const match = oldItem.name === newItem.name; const wasEnabled = oldItem.enabled; // Was enabled in the old array const isDisabled = !newItem.enabled; // Is disabled in the new array diff --git a/src/seqta/utils/onError.js b/src/seqta/utils/onError.js deleted file mode 100644 index e2eab4d6..00000000 --- a/src/seqta/utils/onError.js +++ /dev/null @@ -1 +0,0 @@ -export function onError (error) { console.log(`Error: ${error}`) } \ No newline at end of file diff --git a/src/seqta/utils/onError.ts b/src/seqta/utils/onError.ts new file mode 100644 index 00000000..9f93b1bf --- /dev/null +++ b/src/seqta/utils/onError.ts @@ -0,0 +1 @@ +export function onError (error: string) { console.log(`Error: ${error}`) } \ No newline at end of file diff --git a/src/seqta/utils/stringToHTML.js b/src/seqta/utils/stringToHTML.ts similarity index 83% rename from src/seqta/utils/stringToHTML.js rename to src/seqta/utils/stringToHTML.ts index 4941620b..37449f60 100644 --- a/src/seqta/utils/stringToHTML.js +++ b/src/seqta/utils/stringToHTML.ts @@ -1,6 +1,6 @@ import DOMPurify from 'dompurify'; -export default function stringToHTML(str, styles = false) { +export default function stringToHTML(str: string, styles = false) { var parser = new DOMParser(); str = DOMPurify.sanitize(str, { ADD_ATTR: ['onclick'] }); var doc = parser.parseFromString(str, 'text/html'); diff --git a/tsconfig.json b/tsconfig.json index 647e9a3e..3000138d 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,9 +1,9 @@ { "compilerOptions": { - "target": "ES2016", + "target": "ESNext", "useDefineForClassFields": true, - "lib": ["ES2016", "DOM", "DOM.Iterable"], - "module": "ES2015", + "lib": ["ESNext", "DOM", "DOM.Iterable"], + "module": "ESNext", "skipLibCheck": true, /* Bundler mode */ @@ -18,6 +18,6 @@ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, - "noFallthroughCasesInSwitch": true + "noFallthroughCasesInSwitch": true, }, } diff --git a/webpack.config.js b/webpack.config.js index 3ce548db..0dac62ac 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -16,8 +16,8 @@ export default { }, devtool: 'cheap-module-source-map', entry: { - SEQTA: './src/SEQTA.js', - background: './src/background.js', + SEQTA: './src/SEQTA.ts', + background: './src/background.ts', 'css/documentload': './src/css/documentload.scss', 'css/iframe': './src/css/iframe.scss', 'css/injected': './src/css/injected.scss',