diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 00000000..68d9b5d1 --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,17 @@ +{ + "env": { + "browser": true, + "commonjs": true, + "es2021": true + }, + "extends": "eslint:recommended", + "parserOptions": { + "ecmaVersion": "latest" + }, + "rules": { + "indent": ["error", 2], + "linebreak-style": ["error", "unix"], + "quotes": ["error", "double"], + "semi": ["error", "always"] + } +} diff --git a/.gitignore b/.gitignore index fb61e0ec..7c2833ec 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,4 @@ package-lock.json build/ -.DS_Store \ No newline at end of file +.DS_Store/ \ No newline at end of file diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 00000000..378eac25 --- /dev/null +++ b/.prettierignore @@ -0,0 +1 @@ +build diff --git a/README.md b/README.md index 191c2034..cf34518a 100644 --- a/README.md +++ b/README.md @@ -2,28 +2,29 @@ ![Logo](https://raw.githubusercontent.com/SethBurkart123/BetterThanBetterSeqta/c96edd5956fc11571408310aea98cf7222d6876f/src/icons/betterseqta-dark-full.png#gh-light-mode-only) # Even BetterSEQTA + Forking the BetterSEQTA project to add extra functionality Looking for contributors! ## Table of contents + - [Features](#features) - [Getting Started](#getting-started) - [Contributing](#contributing) - ## Features -* Dark mode +- Dark mode - Custom Background -* Improved Styling/CSS +- Improved Styling/CSS - Improved look for SEQTA Learn -* Custom Home Page including: +- Custom Home Page including: - Daily Lessons - Shortcuts - Easier Access Notices -* Options to remove certain items from the side menu -* Notification for next lesson (sent 5 minutes prior to lesson end) -* Browser Support +- Options to remove certain items from the side menu +- Notification for next lesson (sent 5 minutes prior to lesson end) +- Browser Support - Chrome Supported - Edge Supported - Brave Supported @@ -32,14 +33,19 @@ Looking for contributors! ## Getting started 1. Clone the repository + ``` git clone https://github.com/SethBurkart123/EvenBetterSEQTA ``` + 2. Install dependencies + ``` npm install ``` + 3. Run the dev script (it updates as you save files) + ``` npm run dev ``` @@ -60,4 +66,4 @@ If you would like to contribute to this project, please read the [contributing g ## Credits -This extension was initially developed by [Nulkem](https://github.com/Nulkem/betterseqta), was ported to manifest V3 by [OG-RandomTechChannel](https://github.com/OG-RandomTechChannel) and is currently under active development by [SethBurkart](https://github.com/SethBurkart123) \ No newline at end of file +This extension was initially developed by [Nulkem](https://github.com/Nulkem/betterseqta), was ported to manifest V3 by [OG-RandomTechChannel](https://github.com/OG-RandomTechChannel) and is currently under active development by [SethBurkart](https://github.com/SethBurkart123) diff --git a/contributing.md b/contributing.md index b9f961ee..e4488947 100644 --- a/contributing.md +++ b/contributing.md @@ -1,7 +1,7 @@ # Contributing When contributing to this repository, please first discuss the change you wish to make via issue, -email, or any other method with the owners of this repository before making a change. +email, or any other method with the owners of this repository before making a change. ## Pull Request Process diff --git a/package.json b/package.json index a7959e02..4427ded7 100644 --- a/package.json +++ b/package.json @@ -13,8 +13,12 @@ "devDependencies": { "copy-webpack-plugin": "^11.0.0", "css-loader": "^6.8.1", + "eslint": "^8.48.0", + "eslint-config-prettier": "^9.0.0", + "eslint-webpack-plugin": "^4.0.1", "file-loader": "^6.2.0", "mini-css-extract-plugin": "^2.7.6", + "prettier": "3.0.2", "sass": "^1.65.1", "sass-loader": "^13.3.2", "style-loader": "^3.3.3", diff --git a/public/manifest.json b/public/manifest.json index a60f2035..f15ae02d 100644 --- a/public/manifest.json +++ b/public/manifest.json @@ -1,78 +1,48 @@ { -"manifest_version": 3, - "name": "Even BetterSEQTA", - "version": "3.0.0", - "description": "An extension that makes the SEQTA experience customizable and unique to you!", - "icons": { - "48": "icons/icon-48.png" + "manifest_version": 3, + "name": "Even BetterSEQTA", + "version": "3.0.0", + "description": "An extension that makes the SEQTA experience customizable and unique to you!", + "icons": { + "48": "icons/icon-48.png" + }, + "action": { + "browser_style": true, + "default_popup": "popup/info.html", + "default_icon": { + "32": "icons/icon-32.png", + "64": "icons/icon-64.png" + } + }, + "permissions": ["tabs", "notifications", "storage"], + "host_permissions": ["https://newsapi.org/", "*://*/*"], + "background": { + "service_worker": "background.js" + }, + "optional_permissions": ["declarativeContent"], + "content_scripts": [ + { + "matches": ["https://*.edu.au/*"], + "js": ["purify.min.js", "SEQTA.js"], + "run_at": "document_start" + } + ], + "web_accessible_resources": [ + { + "resources": ["icons/*"], + "matches": ["*://*/*"] }, - "action": { - "browser_style": true, - "default_popup": "popup/info.html", - "default_icon": { - "32": "icons/icon-32.png", - "64": "icons/icon-64.png" - } + { + "resources": ["images/*"], + "matches": ["*://*/*"] }, - "permissions": [ - "tabs", - "notifications", - "storage" - ], - "host_permissions": [ - "https://newsapi.org/", - "*://*/*" - ], - "background": { - "service_worker": "background.js" + { + "resources": ["inject/*"], + "matches": ["*://*/*"] }, - "optional_permissions": [ - "declarativeContent" - ], - "content_scripts": [ - { - "matches": [ - "https://*.edu.au/*" - ], - "js": [ - "purify.min.js", - "SEQTA.js" - ], - "run_at": "document_start" - } - ], - "web_accessible_resources": [ - { - "resources": [ - "icons/*" - ], - "matches": [ - "*://*/*" - ] - }, - { - "resources": [ - "images/*" - ], - "matches": [ - "*://*/*" - ] - }, - { - "resources": [ - "inject/*" - ], - "matches": [ - "*://*/*" - ] - }, - { - "resources": [ - "popup/*" - ], - "matches": [ - "*://*/*" - ] - } - ] + { + "resources": ["popup/*"], + "matches": ["*://*/*"] + } + ] } diff --git a/public/popup/coloris.css b/public/popup/coloris.css index 018eebb1..b7eadf2b 100644 --- a/public/popup/coloris.css +++ b/public/popup/coloris.css @@ -7,7 +7,9 @@ border-radius: 10px; background-color: #fff; justify-content: space-between; - box-shadow: 0 0 5px rgba(0,0,0,.05), 0 5px 20px rgba(0,0,0,.1); + box-shadow: + 0 0 5px rgba(0, 0, 0, 0.05), + 0 5px 20px rgba(0, 0, 0, 0.1); -moz-user-select: none; -webkit-user-select: none; user-select: none; @@ -23,7 +25,8 @@ height: 100px; margin-bottom: 15px; border-radius: 3px 3px 0 0; - background-image: linear-gradient(rgba(0,0,0,0), #000), linear-gradient(90deg, #fff, currentColor); + background-image: linear-gradient(rgba(0, 0, 0, 0), #000), + linear-gradient(90deg, #fff, currentColor); cursor: pointer; } @@ -62,7 +65,16 @@ } .clr-hue { - background-image: linear-gradient(to right, #f00 0%, #ff0 16.66%, #0f0 33.33%, #0ff 50%, #00f 66.66%, #f0f 83.33%, #f00 100%); + background-image: linear-gradient( + to right, + #f00 0%, + #ff0 16.66%, + #0f0 33.33%, + #0ff 50%, + #00f 66.66%, + #f0f 83.33%, + #f00 100% + ); } .clr-hue, @@ -79,7 +91,7 @@ height: 100%; width: 100%; border-radius: inherit; - background-image: linear-gradient(90deg, rgba(0,0,0,0), currentColor); + background-image: linear-gradient(90deg, rgba(0, 0, 0, 0), currentColor); } .clr-hue input, @@ -114,7 +126,7 @@ } .clr-alpha div:before { - content: ''; + content: ""; position: absolute; height: 100%; width: 100%; @@ -206,7 +218,7 @@ } .clr-swatches button:after { - content: ''; + content: ""; display: block; position: absolute; width: 100%; @@ -215,7 +227,7 @@ top: 0; border-radius: inherit; background-color: currentColor; - box-shadow: inset 0 0 0 1px rgba(0,0,0,.1); + box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.1); } input.clr-color { @@ -268,7 +280,7 @@ input.clr-color:focus { .clr-preview:before, .clr-preview:after { - content: ''; + content: ""; position: absolute; height: 100%; width: 100%; @@ -281,7 +293,7 @@ input.clr-color:focus { .clr-preview:after { border: 0; background-color: currentColor; - box-shadow: inset 0 0 0 1px rgba(0,0,0,.1); + box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.1); } .clr-marker, @@ -313,7 +325,7 @@ input.clr-color:focus { } .clr-field button:after { - content: ''; + content: ""; display: block; position: absolute; width: 100%; @@ -322,7 +334,7 @@ input.clr-color:focus { top: 0; border-radius: inherit; background-color: currentColor; - box-shadow: inset 0 0 1px rgba(0,0,0,.5); + box-shadow: inset 0 0 1px rgba(0, 0, 0, 0.5); } .clr-alpha, @@ -330,8 +342,25 @@ input.clr-color:focus { .clr-swatches button, .clr-preview:before, .clr-field button { - background-image: repeating-linear-gradient(45deg, #aaa 25%, transparent 25%, transparent 75%, #aaa 75%, #aaa), repeating-linear-gradient(45deg, #aaa 25%, #fff 25%, #fff 75%, #aaa 75%, #aaa); - background-position: 0 0, 4px 4px; + background-image: repeating-linear-gradient( + 45deg, + #aaa 25%, + transparent 25%, + transparent 75%, + #aaa 75%, + #aaa + ), + repeating-linear-gradient( + 45deg, + #aaa 25%, + #fff 25%, + #fff 75%, + #aaa 75%, + #aaa + ); + background-position: + 0 0, + 4px 4px; background-size: 8px 8px; } @@ -344,7 +373,9 @@ input.clr-color:focus { .clr-keyboard-nav .clr-alpha input:focus + div, .clr-keyboard-nav .clr-segmented input:focus + label { outline: none; - box-shadow: 0 0 0 2px #1e90ff, 0 0 2px 2px #fff; + box-shadow: + 0 0 0 2px #1e90ff, + 0 0 2px 2px #fff; } .clr-picker[data-alpha="false"] .clr-alpha { @@ -374,7 +405,7 @@ input.clr-color:focus { } .clr-dark .clr-swatches button:after { - box-shadow: inset 0 0 0 1px rgba(255,255,255,.3); + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.3); } .clr-dark input.clr-color { @@ -388,25 +419,42 @@ input.clr-color:focus { } .clr-dark .clr-preview:after { - box-shadow: inset 0 0 0 1px rgba(255,255,255,.5); + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.5); } .clr-dark .clr-alpha, .clr-dark .clr-alpha div, .clr-dark .clr-swatches button, .clr-dark .clr-preview:before { - background-image: repeating-linear-gradient(45deg, #666 25%, transparent 25%, transparent 75%, #888 75%, #888), repeating-linear-gradient(45deg, #888 25%, #444 25%, #444 75%, #888 75%, #888); + background-image: repeating-linear-gradient( + 45deg, + #666 25%, + transparent 25%, + transparent 75%, + #888 75%, + #888 + ), + repeating-linear-gradient( + 45deg, + #888 25%, + #444 25%, + #444 75%, + #888 75%, + #888 + ); } /** Polaroid theme **/ .clr-picker.clr-polaroid { border-radius: 6px; - box-shadow: 0 0 5px rgba(0,0,0,.1), 0 5px 30px rgba(0,0,0,.2); + box-shadow: + 0 0 5px rgba(0, 0, 0, 0.1), + 0 5px 30px rgba(0, 0, 0, 0.2); } .clr-picker.clr-polaroid:before { - content: ''; + content: ""; display: block; position: absolute; width: 16px; @@ -418,7 +466,7 @@ input.clr-color:focus { border-bottom-color: currentColor; box-sizing: border-box; color: #fff; - filter: drop-shadow(0 -4px 3px rgba(0,0,0,.1)); + filter: drop-shadow(0 -4px 3px rgba(0, 0, 0, 0.1)); pointer-events: none; } @@ -454,7 +502,7 @@ input.clr-color:focus { .clr-polaroid .clr-hue div, .clr-polaroid .clr-alpha div { - box-shadow: 0 0 5px rgba(0,0,0,.2); + box-shadow: 0 0 5px rgba(0, 0, 0, 0.2); } .clr-polaroid .clr-format { diff --git a/public/popup/coloris.js b/public/popup/coloris.js index e9c31c2d..50471393 100644 --- a/public/popup/coloris.js +++ b/public/popup/coloris.js @@ -5,20 +5,32 @@ */ ((window, document, Math) => { - const ctx = document.createElement('canvas').getContext('2d'); + const ctx = document.createElement("canvas").getContext("2d"); const currentColor = { r: 0, g: 0, b: 0, h: 0, s: 0, v: 0, a: 1 }; - let picker, colorArea, colorAreaDims, colorMarker, colorPreview, colorValue, clearButton, - hueSlider, hueMarker, alphaSlider, alphaMarker, currentEl, currentFormat, oldColor; + let picker, + colorArea, + colorAreaDims, + colorMarker, + colorPreview, + colorValue, + clearButton, + hueSlider, + hueMarker, + alphaSlider, + alphaMarker, + currentEl, + currentFormat, + oldColor; // Default settings const settings = { - el: '.coloris', + el: ".coloris", parent: null, - theme: 'default', - themeMode: 'light', + theme: "default", + themeMode: "light", wrap: true, margin: 2, - format: 'hex', + format: "hex", formatToggle: false, swatches: [], swatchesOnly: false, @@ -27,19 +39,20 @@ autoClose: false, clearButton: { show: false, - label: 'Clear' + label: "Clear", }, a11y: { - open: 'Open color picker', - close: 'Close color picker', - marker: 'Saturation: {s}. Brightness: {v}.', - hueSlider: 'Hue slider', - alphaSlider: 'Opacity slider', - input: 'Color value field', - format: 'Color format', - swatch: 'Color swatch', - instruction: 'Saturation and brightness selector. Use up, down, left and right arrow keys to select.' - } + open: "Open color picker", + close: "Close color picker", + marker: "Saturation: {s}. Brightness: {v}.", + hueSlider: "Hue slider", + alphaSlider: "Opacity slider", + input: "Color value field", + format: "Color format", + swatch: "Color swatch", + instruction: + "Saturation and brightness selector. Use up, down, left and right arrow keys to select.", + }, }; /** @@ -47,81 +60,93 @@ * @param {object} options Configuration options. */ function configure(options) { - if (typeof options !== 'object') { + if (typeof options !== "object") { return; } for (const key in options) { switch (key) { - case 'el': + case "el": bindFields(options.el); if (options.wrap !== false) { wrapFields(options.el); } break; - case 'parent': + case "parent": settings.parent = document.querySelector(options.parent); if (settings.parent) { settings.parent.appendChild(picker); } break; - case 'themeMode': + case "themeMode": settings.themeMode = options.themeMode; - if (options.themeMode === 'auto' && window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) { - settings.themeMode = 'dark'; + if ( + options.themeMode === "auto" && + window.matchMedia && + window.matchMedia("(prefers-color-scheme: dark)").matches + ) { + settings.themeMode = "dark"; } // The lack of a break statement is intentional - case 'theme': + case "theme": if (options.theme) { settings.theme = options.theme; } picker.className = `clr-picker clr-${settings.theme} clr-${settings.themeMode}`; break; - case 'margin': + case "margin": options.margin *= 1; - settings.margin = !isNaN(options.margin) ? options.margin : settings.margin; + settings.margin = !isNaN(options.margin) + ? options.margin + : settings.margin; break; - case 'wrap': + case "wrap": if (options.el && options.wrap) { wrapFields(options.el); } break; - case 'formatToggle': - getEl('clr-format').style.display = options.formatToggle ? 'block' : 'none'; + case "formatToggle": + getEl("clr-format").style.display = options.formatToggle + ? "block" + : "none"; if (options.formatToggle) { - settings.format = 'auto'; + settings.format = "auto"; } break; - case 'swatches': + case "swatches": if (Array.isArray(options.swatches)) { const swatches = []; options.swatches.forEach((swatch, i) => { - swatches.push(``); + swatches.push( + ``, + ); }); if (swatches.length) { - getEl('clr-swatches').innerHTML = `
${swatches.join('')}
`; + getEl("clr-swatches").innerHTML = `
${swatches.join( + "", + )}
`; } } break; - case 'swatchesOnly': + case "swatchesOnly": settings.swatchesOnly = !!options.swatchesOnly; - picker.setAttribute('data-minimal', settings.swatchesOnly); + picker.setAttribute("data-minimal", settings.swatchesOnly); if (settings.swatchesOnly) { settings.autoClose = true; } break; - case 'alpha': + case "alpha": settings.alpha = !!options.alpha; - picker.setAttribute('data-alpha', settings.alpha); + picker.setAttribute("data-alpha", settings.alpha); break; - case 'clearButton': - let display = 'none'; + case "clearButton": + let display = "none"; if (options.clearButton.show) { - display = 'block'; + display = "block"; } if (options.clearButton.label) { @@ -130,11 +155,11 @@ clearButton.style.display = display; break; - case 'a11y': + case "a11y": const labels = options.a11y; let update = false; - if (typeof labels === 'object') { + if (typeof labels === "object") { for (const label in labels) { if (labels[label] && settings.a11y[label]) { settings.a11y[label] = labels[label]; @@ -144,16 +169,16 @@ } if (update) { - const openLabel = getEl('clr-open-label'); - const swatchLabel = getEl('clr-swatch-label'); + const openLabel = getEl("clr-open-label"); + const swatchLabel = getEl("clr-swatch-label"); openLabel.innerHTML = settings.a11y.open; swatchLabel.innerHTML = settings.a11y.swatch; - colorPreview.setAttribute('aria-label', settings.a11y.close); - hueSlider.setAttribute('aria-label', settings.a11y.hueSlider); - alphaSlider.setAttribute('aria-label', settings.a11y.alphaSlider); - colorValue.setAttribute('aria-label', settings.a11y.input); - colorArea.setAttribute('aria-label', settings.a11y.instruction); + colorPreview.setAttribute("aria-label", settings.a11y.close); + hueSlider.setAttribute("aria-label", settings.a11y.hueSlider); + alphaSlider.setAttribute("aria-label", settings.a11y.alphaSlider); + colorValue.setAttribute("aria-label", settings.a11y.input); + colorArea.setAttribute("aria-label", settings.a11y.instruction); } default: settings[key] = options[key]; @@ -167,7 +192,7 @@ */ function bindFields(selector) { // Show the color picker on click on the input fields that match the selector - addListener(document, 'click', selector, event => { + addListener(document, "click", selector, (event) => { const parent = settings.parent; const coords = event.target.getBoundingClientRect(); const scrollY = window.scrollY; @@ -179,7 +204,7 @@ currentEl = event.target; oldColor = currentEl.value; currentFormat = getColorFormatFromStr(oldColor); - picker.classList.add('clr-open'); + picker.classList.add("clr-open"); const pickerWidth = picker.offsetWidth; const pickerHeight = picker.offsetHeight; @@ -215,21 +240,24 @@ reposition.left = true; } - if (top + pickerHeight - scrollY > document.documentElement.clientHeight) { + if ( + top + pickerHeight - scrollY > + document.documentElement.clientHeight + ) { top = scrollY + coords.y - pickerHeight - settings.margin; reposition.top = true; } } - picker.classList.toggle('clr-left', reposition.left); - picker.classList.toggle('clr-top', reposition.top); + picker.classList.toggle("clr-left", reposition.left); + picker.classList.toggle("clr-top", reposition.top); picker.style.left = `${left}px`; picker.style.top = `${top}px`; colorAreaDims = { width: colorArea.offsetWidth, height: colorArea.offsetHeight, x: picker.offsetLeft + colorArea.offsetLeft + offset.x, - y: picker.offsetTop + colorArea.offsetTop + offset.y + y: picker.offsetTop + colorArea.offsetTop + offset.y, }; setColorFromStr(oldColor); @@ -240,11 +268,11 @@ }); // Update the color preview of the input fields that match the selector - addListener(document, 'input', selector, event => { + addListener(document, "input", selector, (event) => { const parent = event.target.parentNode; // Only update the preview if the field has been previously wrapped - if (parent.classList.contains('clr-field')) { + if (parent.classList.contains("clr-field")) { parent.style.color = event.target.value; } }); @@ -255,15 +283,15 @@ * @param {string} selector One or more selectors pointing to input fields. */ function wrapFields(selector) { - document.querySelectorAll(selector).forEach(field => { + document.querySelectorAll(selector).forEach((field) => { const parentNode = field.parentNode; - if (!parentNode.classList.contains('clr-field')) { - const wrapper = document.createElement('div'); + if (!parentNode.classList.contains("clr-field")) { + const wrapper = document.createElement("div"); wrapper.innerHTML = ``; parentNode.insertBefore(wrapper, field); - wrapper.setAttribute('class', 'clr-field'); + wrapper.setAttribute("class", "clr-field"); wrapper.style.color = field.value; wrapper.appendChild(field); } @@ -281,14 +309,14 @@ currentEl.value = oldColor; // Trigger an "input" event to force update the thumbnail next to the input field - currentEl.dispatchEvent(new Event('input', { bubbles: true })); + currentEl.dispatchEvent(new Event("input", { bubbles: true })); } if (oldColor !== currentEl.value) { - currentEl.dispatchEvent(new Event('change', { bubbles: true })); + currentEl.dispatchEvent(new Event("change", { bubbles: true })); } - picker.classList.remove('clr-open'); + picker.classList.remove("clr-open"); if (settings.focusInput) { currentEl.focus({ preventScroll: true }); @@ -312,10 +340,12 @@ // Update the UI hueSlider.value = hsva.h; picker.style.color = `hsl(${hsva.h}, 100%, 50%)`; - hueMarker.style.left = `${hsva.h / 360 * 100}%`; + hueMarker.style.left = `${(hsva.h / 360) * 100}%`; - colorMarker.style.left = `${colorAreaDims.width * hsva.s / 100}px`; - colorMarker.style.top = `${colorAreaDims.height - (colorAreaDims.height * hsva.v / 100)}px`; + colorMarker.style.left = `${(colorAreaDims.width * hsva.s) / 100}px`; + colorMarker.style.top = `${ + colorAreaDims.height - (colorAreaDims.height * hsva.v) / 100 + }px`; alphaSlider.value = hsva.a * 100; alphaMarker.style.left = `${hsva.a * 100}%`; @@ -329,11 +359,11 @@ function getColorFormatFromStr(str) { const format = str.substring(0, 3).toLowerCase(); - if (format === 'rgb' || format === 'hsl') { + if (format === "rgb" || format === "hsl") { return format; } - return 'hex'; + return "hex"; } /** @@ -343,7 +373,7 @@ function pickColor(color) { if (currentEl) { currentEl.value = color !== undefined ? color : colorValue.value; - currentEl.dispatchEvent(new Event('input', { bubbles: true })); + currentEl.dispatchEvent(new Event("input", { bubbles: true })); } } @@ -355,9 +385,9 @@ function setColorAtPosition(x, y) { const hsva = { h: hueSlider.value * 1, - s: x / colorAreaDims.width * 100, - v: 100 - (y / colorAreaDims.height * 100), - a: alphaSlider.value / 100 + s: (x / colorAreaDims.width) * 100, + v: 100 - (y / colorAreaDims.height) * 100, + a: alphaSlider.value / 100, }; const rgba = HSVAtoRGBA(hsva); @@ -376,9 +406,9 @@ saturation = saturation.toFixed(1) * 1; value = value.toFixed(1) * 1; - label = label.replace('{s}', saturation); - label = label.replace('{v}', value); - colorMarker.setAttribute('aria-label', label); + label = label.replace("{s}", saturation); + label = label.replace("{v}", value); + colorMarker.setAttribute("aria-label", label); } // @@ -390,7 +420,7 @@ function getPointerPosition(event) { return { pageX: event.changedTouches ? event.changedTouches[0].pageX : event.pageX, - pageY: event.changedTouches ? event.changedTouches[0].pageY : event.pageY + pageY: event.changedTouches ? event.changedTouches[0].pageY : event.pageY, }; } @@ -407,8 +437,8 @@ y += settings.parent.scrollTop; } - x = (x < 0) ? 0 : (x > colorAreaDims.width) ? colorAreaDims.width : x; - y = (y < 0) ? 0 : (y > colorAreaDims.height) ? colorAreaDims.height : y; + x = x < 0 ? 0 : x > colorAreaDims.width ? colorAreaDims.width : x; + y = y < 0 ? 0 : y > colorAreaDims.height ? colorAreaDims.height : y; colorMarker.style.left = `${x}px`; colorMarker.style.top = `${y}px`; @@ -426,8 +456,8 @@ * * @param {number} offsetY The vertical amount to move. */ function moveMarkerOnKeydown(offsetX, offsetY) { - const x = colorMarker.style.left.replace('px', '') * 1 + offsetX; - const y = colorMarker.style.top.replace('px', '') * 1 + offsetY; + const x = colorMarker.style.left.replace("px", "") * 1 + offsetX; + const y = colorMarker.style.top.replace("px", "") * 1 + offsetY; colorMarker.style.left = `${x}px`; colorMarker.style.top = `${y}px`; @@ -460,27 +490,27 @@ colorPreview.style.color = hex; // Force repaint the color and alpha gradients as a workaround for a Google Chrome bug - colorArea.style.display = 'none'; + colorArea.style.display = "none"; colorArea.offsetHeight; - colorArea.style.display = ''; - alphaMarker.nextElementSibling.style.display = 'none'; + colorArea.style.display = ""; + alphaMarker.nextElementSibling.style.display = "none"; alphaMarker.nextElementSibling.offsetHeight; - alphaMarker.nextElementSibling.style.display = ''; + alphaMarker.nextElementSibling.style.display = ""; - if (format === 'mixed') { - format = currentColor.a === 1 ? 'hex' : 'rgb'; - } else if (format === 'auto') { + if (format === "mixed") { + format = currentColor.a === 1 ? "hex" : "rgb"; + } else if (format === "auto") { format = currentFormat; } switch (format) { - case 'hex': + case "hex": colorValue.value = hex; break; - case 'rgb': + case "rgb": colorValue.value = RGBAToStr(currentColor); break; - case 'hsl': + case "hsl": colorValue.value = HSLAToStr(HSVAtoHSLA(currentColor)); break; } @@ -494,11 +524,11 @@ */ function setHue() { const hue = hueSlider.value * 1; - const x = colorMarker.style.left.replace('px', '') * 1; - const y = colorMarker.style.top.replace('px', '') * 1; + const x = colorMarker.style.left.replace("px", "") * 1; + const y = colorMarker.style.top.replace("px", "") * 1; picker.style.color = `hsl(${hue}, 100%, 50%)`; - hueMarker.style.left = `${hue / 360 * 100}%`; + hueMarker.style.left = `${(hue / 360) * 100}%`; setColorAtPosition(x, y); } @@ -524,11 +554,11 @@ const value = hsva.v / 100; let chroma = saturation * value; let hueBy60 = hsva.h / 60; - let x = chroma * (1 - Math.abs(hueBy60 % 2 - 1)); + let x = chroma * (1 - Math.abs((hueBy60 % 2) - 1)); let m = value - chroma; - chroma = (chroma + m); - x = (x + m); + chroma = chroma + m; + x = x + m; const index = Math.floor(hueBy60) % 6; const red = [chroma, x, m, m, x, chroma][index]; @@ -539,7 +569,7 @@ r: Math.round(red * 255), g: Math.round(green * 255), b: Math.round(blue * 255), - a: hsva.a + a: hsva.a, }; } @@ -550,18 +580,20 @@ */ function HSVAtoHSLA(hsva) { const value = hsva.v / 100; - const lightness = value * (1 - (hsva.s / 100) / 2); + const lightness = value * (1 - hsva.s / 100 / 2); let saturation; if (lightness > 0 && lightness < 1) { - saturation = Math.round((value - lightness) / Math.min(lightness, 1 - lightness) * 100); + saturation = Math.round( + ((value - lightness) / Math.min(lightness, 1 - lightness)) * 100, + ); } return { h: hsva.h, s: saturation || 0, l: Math.round(lightness * 100), - a: hsva.a + a: hsva.a, }; } @@ -582,10 +614,18 @@ let saturation = 0; if (chroma) { - if (xmax === red) { hue = ((green - blue) / chroma); } - if (xmax === green) { hue = 2 + (blue - red) / chroma; } - if (xmax === blue) { hue = 4 + (red - green) / chroma; } - if (xmax) { saturation = chroma / xmax; } + if (xmax === red) { + hue = (green - blue) / chroma; + } + if (xmax === green) { + hue = 2 + (blue - red) / chroma; + } + if (xmax === blue) { + hue = 4 + (red - green) / chroma; + } + if (xmax) { + saturation = chroma / xmax; + } } hue = Math.floor(hue * 60); @@ -594,7 +634,7 @@ h: hue < 0 ? hue + 360 : hue, s: Math.round(saturation * 100), v: Math.round(value * 100), - a: rgba.a + a: rgba.a, }; } @@ -604,11 +644,12 @@ * @return {object} Red, green, blue and alpha values. */ function strToRGBA(str) { - const regex = /^((rgba)|rgb)[\D]+([\d.]+)[\D]+([\d.]+)[\D]+([\d.]+)[\D]*?([\d.]+|$)/i; + const regex = + /^((rgba)|rgb)[\D]+([\d.]+)[\D]+([\d.]+)[\D]+([\d.]+)[\D]*?([\d.]+|$)/i; let match, rgba; // Default to black for invalid color strings - ctx.fillStyle = '#000'; + ctx.fillStyle = "#000"; // Use canvas to convert the string to a valid color string ctx.fillStyle = str; @@ -619,16 +660,18 @@ r: match[3] * 1, g: match[4] * 1, b: match[5] * 1, - a: match[6] * 1 + a: match[6] * 1, }; - } else { - match = ctx.fillStyle.replace('#', '').match(/.{2}/g).map(h => parseInt(h, 16)); + match = ctx.fillStyle + .replace("#", "") + .match(/.{2}/g) + .map((h) => parseInt(h, 16)); rgba = { r: match[0], g: match[1], b: match[2], - a: 1 + a: 1, }; } @@ -644,30 +687,30 @@ let R = rgba.r.toString(16); let G = rgba.g.toString(16); let B = rgba.b.toString(16); - let A = ''; + let A = ""; if (rgba.r < 16) { - R = '0' + R; + R = "0" + R; } if (rgba.g < 16) { - G = '0' + G; + G = "0" + G; } if (rgba.b < 16) { - B = '0' + B; + B = "0" + B; } if (settings.alpha && rgba.a < 1) { - const alpha = rgba.a * 255 | 0; + const alpha = (rgba.a * 255) | 0; A = alpha.toString(16); if (alpha < 16) { - A = '0' + A; + A = "0" + A; } } - return '#' + R + G + B + A; + return "#" + R + G + B + A; } /** @@ -701,23 +744,23 @@ */ function init() { // Render the UI - picker = document.createElement('div'); - picker.setAttribute('id', 'clr-picker'); - picker.className = 'clr-picker'; + picker = document.createElement("div"); + picker.setAttribute("id", "clr-picker"); + picker.className = "clr-picker"; picker.innerHTML = `` + `
` + '
' + - '
' + + "" + '
' + `` + '
' + - '
' + + "" + '
' + `` + '
' + - '' + - '
' + + "" + + "" + '
' + '
' + `${settings.a11y.format}` + @@ -727,9 +770,9 @@ '' + '' + '' + - '' + - '
' + - '
' + + "" + + "" + + "" + '
' + `` + `` + @@ -740,63 +783,63 @@ document.body.appendChild(picker); // Reference the UI elements - colorArea = getEl('clr-color-area'); - colorMarker = getEl('clr-color-marker'); - clearButton = getEl('clr-clear'); - colorPreview = getEl('clr-color-preview'); - colorValue = getEl('clr-color-value'); - hueSlider = getEl('clr-hue-slider'); - hueMarker = getEl('clr-hue-marker'); - alphaSlider = getEl('clr-alpha-slider'); - alphaMarker = getEl('clr-alpha-marker'); + colorArea = getEl("clr-color-area"); + colorMarker = getEl("clr-color-marker"); + clearButton = getEl("clr-clear"); + colorPreview = getEl("clr-color-preview"); + colorValue = getEl("clr-color-value"); + hueSlider = getEl("clr-hue-slider"); + hueMarker = getEl("clr-hue-marker"); + alphaSlider = getEl("clr-alpha-slider"); + alphaMarker = getEl("clr-alpha-marker"); // Bind the picker to the default selector bindFields(settings.el); wrapFields(settings.el); - addListener(picker, 'mousedown', event => { - picker.classList.remove('clr-keyboard-nav'); + addListener(picker, "mousedown", (event) => { + picker.classList.remove("clr-keyboard-nav"); event.stopPropagation(); }); - addListener(colorArea, 'mousedown', event => { - addListener(document, 'mousemove', moveMarker); + addListener(colorArea, "mousedown", (event) => { + addListener(document, "mousemove", moveMarker); }); - addListener(colorArea, 'touchstart', event => { - document.addEventListener('touchmove', moveMarker, { passive: false }); + addListener(colorArea, "touchstart", (event) => { + document.addEventListener("touchmove", moveMarker, { passive: false }); }); - addListener(colorMarker, 'mousedown', event => { - addListener(document, 'mousemove', moveMarker); + addListener(colorMarker, "mousedown", (event) => { + addListener(document, "mousemove", moveMarker); }); - addListener(colorMarker, 'touchstart', event => { - document.addEventListener('touchmove', moveMarker, { passive: false }); + addListener(colorMarker, "touchstart", (event) => { + document.addEventListener("touchmove", moveMarker, { passive: false }); }); - addListener(colorValue, 'change', event => { + addListener(colorValue, "change", (event) => { setColorFromStr(colorValue.value); pickColor(); }); - addListener(clearButton, 'click', event => { - pickColor(''); + addListener(clearButton, "click", (event) => { + pickColor(""); closePicker(); }); - addListener(colorPreview, 'click', event => { + addListener(colorPreview, "click", (event) => { pickColor(); closePicker(); }); - addListener(document, 'click', '.clr-format input', event => { + addListener(document, "click", ".clr-format input", (event) => { currentFormat = event.target.value; updateColor(); pickColor(); }); - addListener(picker, 'click', '.clr-swatches button', event => { + addListener(picker, "click", ".clr-swatches button", (event) => { setColorFromStr(event.target.textContent); pickColor(); @@ -805,37 +848,39 @@ } }); - addListener(document, 'mouseup', event => { - document.removeEventListener('mousemove', moveMarker); + addListener(document, "mouseup", (event) => { + document.removeEventListener("mousemove", moveMarker); }); - addListener(document, 'touchend', event => { - document.removeEventListener('touchmove', moveMarker); + addListener(document, "touchend", (event) => { + document.removeEventListener("touchmove", moveMarker); }); - addListener(document, 'mousedown', event => { - picker.classList.remove('clr-keyboard-nav'); + addListener(document, "mousedown", (event) => { + picker.classList.remove("clr-keyboard-nav"); closePicker(); }); - addListener(document, 'keydown', event => { - if (event.key === 'Escape') { + addListener(document, "keydown", (event) => { + if (event.key === "Escape") { closePicker(true); - } else if (event.key === 'Tab') { - picker.classList.add('clr-keyboard-nav'); + } else if (event.key === "Tab") { + picker.classList.add("clr-keyboard-nav"); } }); - addListener(document, 'click', '.clr-field button', event => { - event.target.nextElementSibling.dispatchEvent(new Event('click', { bubbles: true })); + addListener(document, "click", ".clr-field button", (event) => { + event.target.nextElementSibling.dispatchEvent( + new Event("click", { bubbles: true }), + ); }); - addListener(colorMarker, 'keydown', event => { + addListener(colorMarker, "keydown", (event) => { const movements = { ArrowUp: [0, -1], ArrowDown: [0, 1], ArrowLeft: [-1, 0], - ArrowRight: [1, 0] + ArrowRight: [1, 0], }; if (Object.keys(movements).indexOf(event.key) !== -1) { @@ -844,9 +889,9 @@ } }); - addListener(colorArea, 'click', moveMarker); - addListener(hueSlider, 'input', setHue); - addListener(alphaSlider, 'input', setAlpha); + addListener(colorArea, "click", moveMarker); + addListener(hueSlider, "input", setHue); + addListener(alphaSlider, "input", setAlpha); } /** @@ -866,11 +911,12 @@ * @param {function} [fn] Event handler if delegation is used. */ function addListener(context, type, selector, fn) { - const matches = Element.prototype.matches || Element.prototype.msMatchesSelector; + const matches = + Element.prototype.matches || Element.prototype.msMatchesSelector; // Delegate event to the target of the selector - if (typeof selector === 'string') { - context.addEventListener(type, event => { + if (typeof selector === "string") { + context.addEventListener(type, (event) => { if (matches.call(event.target, selector)) { fn.call(event.target, event); } @@ -892,17 +938,21 @@ function DOMReady(fn, args) { args = args !== undefined ? args : []; - if (document.readyState !== 'loading') { + if (document.readyState !== "loading") { fn(...args); } else { - document.addEventListener('DOMContentLoaded', () => { + document.addEventListener("DOMContentLoaded", () => { fn(...args); }); } } // Polyfill for Nodelist.forEach - if (NodeList !== undefined && NodeList.prototype && !NodeList.prototype.forEach) { + if ( + NodeList !== undefined && + NodeList.prototype && + !NodeList.prototype.forEach + ) { NodeList.prototype.forEach = Array.prototype.forEach; } @@ -911,13 +961,13 @@ const methods = { set: configure, wrap: wrapFields, - close: closePicker + close: closePicker, }; function Coloris(options) { DOMReady(() => { if (options) { - if (typeof options === 'string') { + if (typeof options === "string") { bindFields(options); } else { configure(options); @@ -937,25 +987,24 @@ // Init the color picker when the DOM is ready DOMReady(init); - })(window, document, Math); Coloris({ - el: '.coloris', - theme: 'large', - themeMode: 'dark', - format: 'hex', + el: ".coloris", + theme: "large", + themeMode: "dark", + format: "hex", alpha: false, swatches: [ - '#471616', - '#1e4716', - '#16473f', - '#161c47', - '#371647', - '#47163f', - '#471627', - '#3a3a3a', - '#ffffff', - '#1a1a1a' - ] -}); \ No newline at end of file + "#471616", + "#1e4716", + "#16473f", + "#161c47", + "#371647", + "#47163f", + "#471627", + "#3a3a3a", + "#ffffff", + "#1a1a1a", + ], +}); diff --git a/public/popup/info.css b/public/popup/info.css index 397cf96f..276af1d0 100644 --- a/public/popup/info.css +++ b/public/popup/info.css @@ -11,7 +11,7 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . */ /* cyrillic-ext */ -@import url('https://fonts.googleapis.com/css?family=Rubik:300,400,500,600'); +@import url("https://fonts.googleapis.com/css?family=Rubik:300,400,500,600"); .outside-container { width: 350px; @@ -65,7 +65,8 @@ text-align: center; text-shadow: 0px 0px 15px rgb(22, 22, 22); } -.apply-changes h3, h5 { +.apply-changes h3, +h5 { margin: 0; } .apply-changes h3 { @@ -129,7 +130,7 @@ p { justify-content: space-between; margin-top: 10px; font-size: 13px !important; - position:relative; + position: relative; } .clr-field input:hover { cursor: pointer; @@ -178,7 +179,8 @@ p { .onoffswitch { margin: 0 0 1ex; - position: relative; width: 42px; + position: relative; + width: 42px; } .onoffswitch-checkbox { position: absolute; @@ -195,33 +197,44 @@ p { } .onoffswitch-label { - display: block; overflow: hidden; cursor: pointer; - height: 16px; padding: 0; line-height: 16px; - border: 0px solid #FFFFFF; border-radius: 24px; - background-color: #9E9E9E; + display: block; + overflow: hidden; + cursor: pointer; + height: 16px; + padding: 0; + line-height: 16px; + border: 0px solid #ffffff; + border-radius: 24px; + background-color: #9e9e9e; } .onoffswitch-label:before { content: ""; - display: block; width: 24px; margin: -4px; height: 24px; - background: #FFFFFF; - position: absolute; top: 0; bottom: 0; + display: block; + width: 24px; + margin: -4px; + height: 24px; + background: #ffffff; + position: absolute; + top: 0; + bottom: 0; right: 22px; border-radius: 24px; transition: 0.3s; } .onoffswitch-checkbox:checked + .onoffswitch-label { - background-color: #20E060; + background-color: #20e060; } -.onoffswitch-checkbox:checked + .onoffswitch-label, .onoffswitch-checkbox:checked + .onoffswitch-label:before { - border-color: #20E060; +.onoffswitch-checkbox:checked + .onoffswitch-label, +.onoffswitch-checkbox:checked + .onoffswitch-label:before { + border-color: #20e060; } .onoffswitch-checkbox:checked + .onoffswitch-label .onoffswitch-inner { margin-left: 0; } .onoffswitch-checkbox:checked + .onoffswitch-label:before { transition: 0.3s; - right: 0px; - background-color: #86F078; + right: 0px; + background-color: #86f078; box-shadow: 3px 6px 18px 0px rgba(0, 0, 0, 0.2); } @@ -272,14 +285,14 @@ p { ::-webkit-scrollbar { width: 10px; height: 10px; - transition: 1.0s; + transition: 1s; } ::-webkit-scrollbar-thumb { background-color: rgba(127, 127, 127, 0.6); background-clip: padding-box; border: 2px solid transparent; - transition: 1.0s; + transition: 1s; } ::-webkit-scrollbar-thumb:vertical:hover, @@ -291,23 +304,23 @@ p { background-color: transparent; } - - ::-webkit-scrollbar-thumb:vertical:active, ::-webkit-scrollbar-thumb:horizontal:active { background: rgba(95, 91, 91, 1); - } ::-webkit-scrollbar-corner { background: none; } -:root, html, body, div, ol { +:root, +html, +body, +div, +ol { scrollbar-width: thin !important; scrollbar-color: #5e5e5f #161616 !important; } - .topmenu { display: flex; width: 100%; @@ -315,7 +328,6 @@ p { color: white; margin-top: 20px; margin-bottom: 20px; - } .navitem { width: 33.34%; @@ -329,7 +341,6 @@ p { border-bottom: 2px solid #a5a5a5; color: #a5a5a5; transition: 0.3s; - } .activenav { border-bottom: 2px solid #ff5f5f; @@ -358,7 +369,8 @@ p { #applychanges { margin-top: 0px; } -.applychanges h5, h6 { +.applychanges h5, +h6 { margin: 0; font-weight: 400; } @@ -366,10 +378,10 @@ p { list-style: none; position: relative; margin-left: 10px; - cursor:grab; + cursor: grab; } .draggable:active { - cursor:-moz-grabbing; + cursor: -moz-grabbing; cursor: -webkit-grabbing; } .draggable::before { @@ -401,18 +413,18 @@ p { transition: 300ms; } -.customshortcut-submit-valid { +.customshortcut-submit-valid { background: #20de5f !important; transition: 300ms; } -.customshortcut-submit-valid:hover { +.customshortcut-submit-valid:hover { background: #1cc956 !important; transition: 300ms; cursor: pointer; } -.customshortcut-submit-valid:active { +.customshortcut-submit-valid:active { background: #17aa48 !important; transition: 300ms; } @@ -459,9 +471,9 @@ p { } .custom-shortcuts-field:focus { - outline: none; - outline: 1px solid rgb(60, 60, 60); - transition: 100ms; + outline: none; + outline: 1px solid rgb(60, 60, 60); + transition: 100ms; } .domain-container { font-size: 9px; diff --git a/public/popup/info.html b/public/popup/info.html index 5470bf1d..76c52271 100644 --- a/public/popup/info.html +++ b/public/popup/info.html @@ -1,4 +1,4 @@ - + + + + + + + - - - - - - + + - - - -
-
-
- - - +
+
-
- - -