diff --git a/css/ui.css b/css/ui.css index b5cdfb4..99a92aa 100644 --- a/css/ui.css +++ b/css/ui.css @@ -23,6 +23,10 @@ button:disabled { background: #939393; cursor: not-allowed; } +label { + color: #bdbdbd; + font-size: 14px; +} #status { margin-top: 10px; font-size: 14px; @@ -46,10 +50,19 @@ button:disabled { background-color: var(--primary-color); border-radius: 8px; } -#rateLimitInput, #formatSelector { - width: 60px; - padding: 4px; +#cover { + display: none; + float: left; + width: 80px; + height: auto; + margin-right: 10px; +} +#rateLimitInput { + width: 80px; + padding: 6px; + font-size: 14px; margin-left: 8px; + margin-right: 8px; text-align: center; background: #252527; color: #fff; @@ -57,7 +70,7 @@ button:disabled { border-radius: 4px; -moz-appearance: textfield; } -#rateLimitInput:focus, #rateLimitInput:hover, #formatSelector:focus, #formatSelector:hover { +#rateLimitInput:focus, #rateLimitInput:hover { outline: none; border-color: var(--primary-color); box-shadow: 0 0 5px var(--primary-color); @@ -71,13 +84,30 @@ input[type="number"] { -moz-appearance: none; -webkit-appearance: none; } -#formatSelector { +#maxSizeInput { width: 80px; + padding: 6px; + font-size: 14px; + margin-left: 8px; + margin-right: 8px; + text-align: center; + background: #252527; + color: #fff; + border: 1px solid #444; + border-radius: 4px; + -moz-appearance: textfield; } -#maxSizeInput, #maxChaptersInput { - width: 60px; - padding: 4px; +#maxSizeInput:focus, #maxSizeInput:hover { + outline: none; + border-color: var(--primary-color); + box-shadow: 0 0 5px var(--primary-color); +} +#maxChaptersInput { + width: 80px; + padding: 6px; + font-size: 14px; margin-left: 8px; + margin-right: 8px; text-align: center; background: #252527; color: #fff; @@ -85,7 +115,6 @@ input[type="number"] { border-radius: 4px; -moz-appearance: textfield; } -#maxSizeInput:focus, #maxSizeInput:hover, #maxChaptersInput:focus, #maxChaptersInput:hover { outline: none; border-color: var(--primary-color); @@ -98,3 +127,154 @@ input[type="number"] { -webkit-appearance: none; margin: 0; } +#releaseDate { + text-align: center; + color: #bdbdbd; + font-size: 12px; + margin-top: 8px; + margin-bottom: 8px; +} +#formatContainer { + text-align: center; + margin-top: 10px; + margin-bottom: 10px; +} +#formatSelector { + width: 80px; + padding: 6px; + font-size: 14px; + margin-left: 8px; + margin-right: 8px; + text-align: center; + background: #252527; + color: #fff; + border: 1px solid #444; + border-radius: 4px; + -moz-appearance: textfield; +} +#formatSelector:focus, #formatSelector:hover { + outline: none; + border-color: var(--primary-color); + box-shadow: 0 0 5px var(--primary-color); +} +#rateLimitContainer { + text-align: center; + margin-top: 10px; + margin-bottom: 10px; +} +#activeDownloadsInfo { + text-align: center; + color: #bdbdbd; + font-size: 12px; + margin-top: 8px; + margin-bottom: 8px; + display: none; +} +#fileInputContainer { + text-align: center; + margin-top: 10px; + margin-bottom: 10px; +} +#fileInput { + display: none; +} +#customFileBtn { + padding: 8px 16px; + cursor: pointer; + font-size: 14px; + transition: all 0.3s ease; +} +#downloadControls { + display: none; + text-align: center; + margin-top: 10px; +} +#pauseBtn { + padding: 8px 16px; + cursor: pointer; + width: calc(50% - 4px); + transition: all 0.3s ease; +} +#backgroundBtn { + padding: 8px 16px; + cursor: pointer; + width: calc(50% - 4px); + transition: all 0.3s ease; +} +#pauseBtn, #backgroundBtn, #customFileBtn { + border: 2px solid var(--primary-color) !important; + background: #252527 !important; +} +#pauseBtn:hover, #backgroundBtn:hover, #customFileBtn:hover { + border: 2px solid var(--secondary-color) !important; + background: #252527 !important; +} +#stopBtn { + margin-top: 12px; + padding: 8px 16px; + cursor: pointer; + display: block; + width: 100%; + transition: all 0.3s ease; +} +#btnRow { + display: flex; + justify-content: space-between; +} +#splitModeContainer { + text-align: center; + margin-top: 10px; + margin-bottom: 5px; +} +#chapterRangeContainer { + text-align: center; + margin-top: 10px; + margin-bottom: 10px; + display: none; +} +#chapterSelectRow { + display: flex; + justify-content: space-between; + align-items: center; +} +#chapterFromLabel { + color: #bdbdbd; + font-size: 14px; + margin-bottom: 2px; + width: 50%; + text-align: center; +} +#chapterToLabel{ + color: #bdbdbd; + font-size: 14px; + margin-bottom: 2px; + width: 50%; + text-align: center; +} +#chapterLabelsRow{ + display: flex; + justify-content: space-between; +} +#chapterFromSelect { + padding: 8px 16px; + font-size: 14px; + width: calc(50% - 4px); + cursor: pointer; + border: 2px solid var(--primary-color); + background: #252527; + color: #bdbdbd; + transition: all 0.3s ease; +} +#chapterToSelect { + padding: 8px 16px; + font-size: 14px; + width: calc(50% - 4px); + cursor: pointer; + border: 2px solid var(--primary-color); + background: #252527; + color: #bdbdbd; + transition: all 0.3s ease; +} +#chapterToSelect:hover, #chapterFromSelect:hover { + border: 2px solid var(--secondary-color); +} diff --git a/tests/ui/PopupController.new.test.js b/tests/ui/PopupController.new.test.js index 562fdbd..48e9c0a 100644 --- a/tests/ui/PopupController.new.test.js +++ b/tests/ui/PopupController.new.test.js @@ -782,34 +782,6 @@ describe('PopupController second test file', () => { expect(fromSelect.value).toBe('1'); }); - it('Changes fromSelect border on mouseenter and restores on mouseleave', async () => { - const controller = new PopupController(); - - await new Promise(resolve => setTimeout(resolve, 100)); - - const fromSelect = document.getElementById('chapterFromSelect'); - - fromSelect.dispatchEvent(new Event('mouseenter')); - expect(fromSelect.style.border).toBe('2px solid var(--secondary-color)'); - - fromSelect.dispatchEvent(new Event('mouseleave')); - expect(fromSelect.style.border).toBe('2px solid var(--primary-color)'); - }); - - it('Changes toSelect border on mouseenter and restores on mouseleave', async () => { - const controller = new PopupController(); - - await new Promise(resolve => setTimeout(resolve, 100)); - - const toSelect = document.getElementById('chapterToSelect'); - - toSelect.dispatchEvent(new Event('mouseenter')); - expect(toSelect.style.border).toBe('2px solid var(--secondary-color)'); - - toSelect.dispatchEvent(new Event('mouseleave')); - expect(toSelect.style.border).toBe('2px solid var(--primary-color)'); - }); - it('Logs no saved format when localStorage has no format and logs UI setup complete', async () => { const logSpy = vi.spyOn(console, 'log'); @@ -966,4 +938,4 @@ describe('PopupController second test file', () => { controller.resetUI(); expect(splitModeContainer.style.display).toBe('block'); }); -}); \ No newline at end of file +}); diff --git a/ui/PopupController.js b/ui/PopupController.js index 6436266..41e62c9 100644 --- a/ui/PopupController.js +++ b/ui/PopupController.js @@ -51,10 +51,6 @@ const btn = document.getElementById('downloadBtn'); const status = document.getElementById('status'); const progress = document.getElementById('progress'); - const siteLogo = document.getElementById('siteLogo'); - const logoInfo = document.getElementById('logoInfo'); - const coverImg = document.getElementById('cover'); - const desc = document.getElementById('description'); if (!btn) { console.error('downloadBtn not found in DOM'); @@ -65,27 +61,16 @@ if (!releaseEl) { releaseEl = document.createElement('div'); releaseEl.id = 'releaseDate'; - releaseEl.style.textAlign = 'center'; - releaseEl.style.color = '#bdbdbd'; - releaseEl.style.fontSize = '12px'; - releaseEl.style.marginTop = '8px'; - releaseEl.style.marginBottom = '8px'; btn.parentNode.insertBefore(releaseEl, btn); } let formatSelector = document.getElementById('formatSelector'); if (!formatSelector) { const formatContainer = document.createElement('div'); - formatContainer.style.textAlign = 'center'; - formatContainer.style.marginTop = '10px'; - formatContainer.style.marginBottom = '10px'; + formatContainer.id = 'formatContainer'; formatSelector = document.createElement('select'); formatSelector.id = 'formatSelector'; - formatSelector.style.padding = '6px 12px'; - formatSelector.style.fontSize = '14px'; - formatSelector.style.marginLeft = '8px'; - formatSelector.style.marginRight = '8px'; global.ExporterRegistry.getFormats().forEach(({ value, label }) => { const option = document.createElement('option'); @@ -96,8 +81,6 @@ const label = document.createElement('label'); label.textContent = 'Формат: '; - label.style.color = '#bdbdbd'; - label.style.fontSize = '14px'; label.htmlFor = 'formatSelector'; formatContainer.appendChild(label); @@ -122,14 +105,10 @@ let rateLimitInput = document.getElementById('rateLimitInput'); if (!rateLimitInput) { const rateLimitContainer = document.createElement('div'); - rateLimitContainer.style.textAlign = 'center'; - rateLimitContainer.style.marginTop = '10px'; - rateLimitContainer.style.marginBottom = '10px'; + rateLimitContainer.id = 'rateLimitContainer'; const label = document.createElement('label'); label.textContent = 'Запросов в минуту: '; - label.style.color = '#bdbdbd'; - label.style.fontSize = '14px'; rateLimitInput = document.createElement('input'); rateLimitInput.id = 'rateLimitInput'; @@ -155,12 +134,6 @@ if (!activeDownloadsInfo) { activeDownloadsInfo = document.createElement('div'); activeDownloadsInfo.id = 'activeDownloadsInfo'; - activeDownloadsInfo.style.textAlign = 'center'; - activeDownloadsInfo.style.color = '#bdbdbd'; - activeDownloadsInfo.style.fontSize = '12px'; - activeDownloadsInfo.style.marginTop = '8px'; - activeDownloadsInfo.style.marginBottom = '8px'; - activeDownloadsInfo.style.display = 'none'; const rateLimitContainer = rateLimitInput.parentNode; rateLimitContainer.parentNode.insertBefore(activeDownloadsInfo, rateLimitContainer.nextSibling); @@ -170,23 +143,15 @@ if (!fileInputContainer) { fileInputContainer = document.createElement('div'); fileInputContainer.id = 'fileInputContainer'; - fileInputContainer.style.textAlign = 'center'; - fileInputContainer.style.marginTop = '10px'; - fileInputContainer.style.marginBottom = '10px'; const hiddenFileInput = document.createElement('input'); hiddenFileInput.type = 'file'; hiddenFileInput.id = 'fileInput'; hiddenFileInput.accept = '.pdf,.epub,.fb2'; - hiddenFileInput.style.display = 'none'; const customFileBtn = document.createElement('button'); customFileBtn.id = 'customFileBtn'; customFileBtn.textContent = 'Загрузить файл для обновления'; - customFileBtn.style.padding = '8px 16px'; - customFileBtn.style.cursor = 'pointer'; - customFileBtn.style.fontSize = '14px'; - customFileBtn.style.transition = 'all 0.3s ease'; fileInputContainer.appendChild(hiddenFileInput); fileInputContainer.appendChild(customFileBtn); @@ -232,55 +197,21 @@ if (!controlsContainer) { controlsContainer = document.createElement('div'); controlsContainer.id = 'downloadControls'; - controlsContainer.style.display = 'none'; - controlsContainer.style.textAlign = 'center'; - controlsContainer.style.marginTop = '10px'; const pauseBtn = document.createElement('button'); pauseBtn.id = 'pauseBtn'; pauseBtn.textContent = 'Пауза'; - pauseBtn.style.padding = '8px 16px'; - pauseBtn.style.cursor = 'pointer'; - pauseBtn.style.width = 'calc(50% - 4px)'; - pauseBtn.style.transition = 'all 0.3s ease'; const backgroundBtn = document.createElement('button'); backgroundBtn.id = 'backgroundBtn'; backgroundBtn.textContent = 'Фоном'; - backgroundBtn.style.padding = '8px 16px'; - backgroundBtn.style.cursor = 'pointer'; - backgroundBtn.style.width = 'calc(50% - 4px)'; - backgroundBtn.style.transition = 'all 0.3s ease'; - - if (!document.getElementById('control-buttons-styles')) { - const styleEl = document.createElement('style'); - styleEl.id = 'control-buttons-styles'; - styleEl.textContent = ` - #pauseBtn, #backgroundBtn, #customFileBtn { - border: 2px solid var(--primary-color) !important; - background: #252527 !important; - } - #pauseBtn:hover, #backgroundBtn:hover, #customFileBtn:hover { - border: 2px solid var(--secondary-color) !important; - background: #252527 !important; - } - `; - document.head.appendChild(styleEl); - } const stopBtn = document.createElement('button'); stopBtn.id = 'stopBtn'; stopBtn.textContent = 'Завершить'; - stopBtn.style.marginTop = '12px'; - stopBtn.style.padding = '8px 16px'; - stopBtn.style.cursor = 'pointer'; - stopBtn.style.display = 'block'; - stopBtn.style.width = '100%'; - stopBtn.style.transition = 'all 0.3s ease'; const btnRow = document.createElement('div'); - btnRow.style.display = 'flex'; - btnRow.style.justifyContent = 'space-between'; + btnRow.id = 'btnRow'; btnRow.appendChild(pauseBtn); btnRow.appendChild(backgroundBtn); @@ -295,14 +226,9 @@ if (!splitModeContainer) { splitModeContainer = document.createElement('div'); splitModeContainer.id = 'splitModeContainer'; - splitModeContainer.style.textAlign = 'center'; - splitModeContainer.style.marginTop = '10px'; - splitModeContainer.style.marginBottom = '5px'; const maxSizeLabel = document.createElement('label'); maxSizeLabel.textContent = 'Макс. размер части (МБ):'; - maxSizeLabel.style.color = '#bdbdbd'; - maxSizeLabel.style.fontSize = '14px'; maxSizeLabel.htmlFor = 'maxSizeInput'; const maxSizeInput = document.createElement('input'); @@ -334,95 +260,47 @@ if (!chapterRangeContainer) { chapterRangeContainer = document.createElement('div'); chapterRangeContainer.id = 'chapterRangeContainer'; - chapterRangeContainer.style.textAlign = 'center'; - chapterRangeContainer.style.marginTop = '10px'; - chapterRangeContainer.style.marginBottom = '10px'; - chapterRangeContainer.style.display = 'none'; - - const selectRow = document.createElement('div'); - selectRow.style.display = 'flex'; - selectRow.style.justifyContent = 'space-between'; - selectRow.style.alignItems = 'center'; - - const fromLabel = document.createElement('div'); - fromLabel.textContent = 'от'; - fromLabel.style.color = '#bdbdbd'; - fromLabel.style.fontSize = '14px'; - fromLabel.style.marginBottom = '2px'; - fromLabel.style.width = '50%'; - fromLabel.style.textAlign = 'center'; - - const toLabel = document.createElement('div'); - toLabel.textContent = 'до'; - toLabel.style.color = '#bdbdbd'; - toLabel.style.fontSize = '14px'; - toLabel.style.marginBottom = '2px'; - toLabel.style.width = '50%'; - toLabel.style.textAlign = 'center'; - - const labelsRow = document.createElement('div'); - labelsRow.style.display = 'flex'; - labelsRow.style.justifyContent = 'space-between'; - labelsRow.appendChild(fromLabel); - labelsRow.appendChild(toLabel); - - const fromSelect = document.createElement('select'); - fromSelect.id = 'chapterFromSelect'; - fromSelect.style.padding = '8px 16px'; - fromSelect.style.fontSize = '14px'; - fromSelect.style.width = 'calc(50% - 4px)'; - fromSelect.style.cursor = 'pointer'; - fromSelect.style.border = '2px solid var(--primary-color)'; - fromSelect.style.background = '#252527'; - fromSelect.style.color = '#bdbdbd'; - fromSelect.style.transition = 'all 0.3s ease'; - - const toSelect = document.createElement('select'); - toSelect.id = 'chapterToSelect'; - toSelect.style.padding = '8px 16px'; - toSelect.style.fontSize = '14px'; - toSelect.style.width = 'calc(50% - 4px)'; - toSelect.style.cursor = 'pointer'; - toSelect.style.border = '2px solid var(--primary-color)'; - toSelect.style.background = '#252527'; - toSelect.style.color = '#bdbdbd'; - toSelect.style.transition = 'all 0.3s ease'; - - fromSelect.addEventListener('change', () => { - const fromIdx = parseInt(fromSelect.value); - const toIdx = parseInt(toSelect.value); - if (fromIdx > toIdx) toSelect.value = fromSelect.value; - else console.log('Chapter range selectors updated without invalid range'); - }); - toSelect.addEventListener('change', () => { - const fromIdx = parseInt(fromSelect.value); - const toIdx = parseInt(toSelect.value); - if (toIdx < fromIdx) fromSelect.value = toSelect.value; - else console.log('Chapter range selectors updated without invalid range'); - }); + const chapterSelectRow = document.createElement('div'); + chapterSelectRow.id = 'chapterSelectRow'; - fromSelect.addEventListener('mouseenter', () => { - fromSelect.style.border = '2px solid var(--secondary-color)'; - }); + const chapterFromLabel = document.createElement('div'); + chapterFromLabel.id = 'chapterFromLabel'; + chapterFromLabel.textContent = 'от'; - fromSelect.addEventListener('mouseleave', () => { - fromSelect.style.border = '2px solid var(--primary-color)'; - }); + const chapterToLabel = document.createElement('div'); + chapterToLabel.id = 'chapterToLabel'; + chapterToLabel.textContent = 'до'; - toSelect.addEventListener('mouseenter', () => { - toSelect.style.border = '2px solid var(--secondary-color)'; - }); + const chapterLabelsRow = document.createElement('div'); + chapterLabelsRow.id = 'chapterLabelsRow'; + chapterLabelsRow.appendChild(chapterFromLabel); + chapterLabelsRow.appendChild(chapterToLabel); + + const chapterFromSelect = document.createElement('select'); + chapterFromSelect.id = 'chapterFromSelect'; - toSelect.addEventListener('mouseleave', () => { - toSelect.style.border = '2px solid var(--primary-color)'; + const chapterToSelect = document.createElement('select'); + chapterToSelect.id = 'chapterToSelect'; + + chapterFromSelect.addEventListener('change', () => { + const fromIdx = parseInt(chapterFromSelect.value); + const toIdx = parseInt(chapterToSelect.value); + if (fromIdx > toIdx) chapterToSelect.value = chapterFromSelect.value; + else console.log('Chapter range selectors updated without invalid range'); }); - selectRow.appendChild(fromSelect); - selectRow.appendChild(toSelect); + chapterToSelect.addEventListener('change', () => { + const fromIdx = parseInt(chapterFromSelect.value); + const toIdx = parseInt(chapterToSelect.value); + if (toIdx < fromIdx) chapterFromSelect.value = chapterToSelect.value; + else console.log('Chapter range selectors updated without invalid range'); + }); + chapterSelectRow.appendChild(chapterFromSelect); + chapterSelectRow.appendChild(chapterToSelect); - chapterRangeContainer.appendChild(labelsRow); - chapterRangeContainer.appendChild(selectRow); + chapterRangeContainer.appendChild(chapterLabelsRow); + chapterRangeContainer.appendChild(chapterSelectRow); const rateLimitContainer = rateLimitInput.parentNode; rateLimitContainer.parentNode.insertBefore(chapterRangeContainer, rateLimitContainer.nextSibling); @@ -668,7 +546,6 @@ if (cover) { coverImg.style.display = 'block'; coverImg.src = cover; - coverImg.setAttribute('style', 'display:block; float:left; width:80px; height:auto; margin-right:10px;'); } else { coverImg.style.display = 'none'; }