Implement minimal adequate frontend

This commit is contained in:
ilyaigpetrov 2025-03-22 05:34:46 +05:00
parent 2bf42ac73e
commit 8d923cc041
2 changed files with 94 additions and 51 deletions

View File

@ -33,6 +33,8 @@
/* Reset ends */ /* Reset ends */
:root { :root {
border-color: black;
border-radius: 0;
/* /*
The initial theme is light but it's quickly inverted to dark. The initial theme is light but it's quickly inverted to dark.
Dark theme should be the first theme user sees by default. Dark theme should be the first theme user sees by default.
@ -81,6 +83,7 @@
vertical-align: text-bottom; vertical-align: text-bottom;
} }
input[type="url"] { input[type="url"] {
border: 1px solid black;
/*border-width: 0 0 1px 0; /*border-width: 0 0 1px 0;
border-color: crimson;*/ border-color: crimson;*/
flex-grow: 1; flex-grow: 1;
@ -90,29 +93,19 @@
input[type="radio"], label { input[type="radio"], label {
cursor: pointer; cursor: pointer;
} }
#disabled:checked + label { #disabledRadio:checked + label {
color: red; color: red;
} }
#ownInputs {
div.nowrap {
/* Don't break sentences on spaces. */
white-space: nowrap;
}
/*
#own:checked + label:after {
content: ":";
}
*/
#own ~ div {
display: flex; display: flex;
} }
/* /*
input#own ~ div:has(> input#customPacUrl):after { input#ownRadio ~ div:has(> input#customPacUrl):after {
border: 5px solid lime; border: 5px solid lime;
background-color: navy; background-color: navy;
content: ""; content: "";
} }
input#own ~ div:after:not(:empty) { input#ownRadio ~ div:after:not(:empty) {
border: 5px solid pink; border: 5px solid pink;
} }
*/ */
@ -154,6 +147,32 @@
#customPacUrl:disabled { #customPacUrl:disabled {
/*background-color: grey;*/ /*background-color: grey;*/
} }
#ownInputs button {
font-family: emoji, monospace;
width: 2em;
width: 2ch;
border-width: 1px 1px 1px 0px;
}
#ownInputs > input {
border-radius: 0;
}
#ownInputs > div {
display: flex;
}
#customPacUrl:disabled ~ .editPanel {
display: none;
}
#customPacUrl:not(:disabled) ~ .unlockPanel {
display: none;
}
#boxes {
padding: 1em 0;
padding: 1ch 0;
}
#boxes > div {
/* Don't break sentences on spaces. */
white-space: nowrap;
}
</style> </style>
</head> </head>
<body class="use-preferred-color-scheme"> <body class="use-preferred-color-scheme">
@ -163,35 +182,50 @@
</header> </header>
<nav> <nav>
<form id="pacChooserForm"> <form id="pacChooserForm">
<ul> <ul id="radios">
<li> <li>
<input type="radio" value="antizapret" name="pacScript" id="antizapret"> <input type="radio" value="antizapret" name="pacScript" id="antizapret">
<label for="antizapret">Антизапрет</label> <label for="antizapret">Антизапрет</label>
</li> </li>
<li> <li>
<input type="radio" value="anticensority" name="pacScript" id="anticensority"> <input type="radio" value="anticensority" name="pacScript" id="anticensorityRadio">
<label for="anticensority">Антицензорити</label> <label for="anticensorityRadio">Антицензорити</label>
<a href title="обновить">[обновить]</a>
<a href title="приостановить">[⏸]</a>
<a href title="информация" style="float: right">[]</a>
</li> </li>
<li> <li>
<input type="radio" value="own" name="pacScript" id="own" disabled> <input type="radio" value="own" name="pacScript" id="ownRadio" disabled>
<label for="own">Свой:</label> <label for="ownRadio">Свой:</label>
<div> <div id="ownInputs">
<input id="customPacUrl" type="url" placeholder="https://example.com/proxy.pac" <input id="customPacUrl" type="url" placeholder="https://example.com/proxy.pac"
size="27" size="27"
spellcheck="false" autocorrect="off" autocapitalize="off" spellcheck="false" autocorrect="off" autocapitalize="off"
disabled required required
> >
<button id="editPacUrlButton" title="Редактировать">🖉</button> <div class="unlockPanel">
<button id="editPacUrlButton" title="Редактировать">🖉</button>
</div>
<div class="editPanel">
<button id="savePacUrlButton" title="Сохранить">🗸</button>
<button id="cancelPacUrlButton" title="Отмена">🗙</button>
</div>
</div> </div>
</li> </li>
<li> <li>
<input type="radio" value="disabled" name="pacScript" id="disabled" checked> <input type="radio" value="disabled" name="pacScript" id="disabledRadio" checked>
<label for="disabled">Отключить / сброс</label> <label for="disabledRadio">Отключить / Сброс</label>
</li> </li>
</ul> </ul>
<div class="nowrap"> <div id="boxes">
<input type="checkbox" name="reset" id="reset" checked> <div>
<label for="reset">Сбрасывать перед переключением</label> <input type="checkbox" name="resetBox" id="resetBox" checked>
<label for="resetBox">Отключать прокси перед скачиванием</label>
</div>
<div>
<input type="checkbox" name="updateBox" id="updateBox" checked>
<label for="updateBox">Обновлять каждые 12ч</label>
</div>
</div> </div>
</form> </form>
</nav> </nav>

View File

@ -1,6 +1,6 @@
console.log('Options page is opening...'); console.log('Options page is opening...');
pacChooserForm.addEventListener('change', function (event) { customPacUrl.addEventListener('change', function (event) {
console.log('ON CHANGE:', event); console.log('ON CHANGE:', event);
pacChooserForm.reportValidity(); pacChooserForm.reportValidity();
}); });
@ -11,34 +11,43 @@ pacChooserForm.addEventListener('formdata', (event) => {
return false; // Prevent default action. return false; // Prevent default action.
}); });
*/ */
editPacUrlButton.onclick = function (event) {
event.preventDefault(); let LAST_LOCKED_URL = '';
const lockUrl = () => { customPacUrl.disabled = true; }; const lockUrl = () => {
const unlockUrl = () => { customPacUrl.disabled = false; };
const ifUrlLocked = customPacUrl.disabled;
if (ifUrlLocked) {
unlockUrl();
return false;
}
const ifUrlValid = customPacUrl.checkValidity(); const ifUrlValid = customPacUrl.checkValidity();
if (ifUrlValid) { if (ifUrlValid) {
lockUrl(); LAST_LOCKED_URL = customPacUrl.value;
own.disabled = false; customPacUrl.disabled = true;
ownRadio.disabled = false;
// TODO: Save to storage. // TODO: Save to storage.
return false; } else {
pacChooserForm.reportValidity();
ownRadio.disabled = true; // `ownRadio.checked` doesn't matter here.
} }
// Empty or incorrect url.
own.disabled = true; // `own.checked` doesn't matter here.
const ifUrlEmpty = !customPacUrl.value;
if (ifUrlEmpty) {
lockUrl();
if (own.checked) {
disabled.checked = true;
}
return false;
}
return false;
}; };
const unlockUrl = () => {
customPacUrl.disabled = false;
customPacUrl.focus();
ownRadio.disabled = true;
};
const suppressDefaultHandler = (f) =>
(event) => {
event.preventDefault();
f(event);
return false;
};
savePacUrlButton.onclick = suppressDefaultHandler(lockUrl);
cancelPacUrlButton.onclick = suppressDefaultHandler(
() => {
customPacUrl.value = LAST_LOCKED_URL;
lockUrl();
},
);
editPacUrlButton.onclick = suppressDefaultHandler(unlockUrl);
/* /*
import { storage } from '../../lib/common-apis.mjs'; import { storage } from '../../lib/common-apis.mjs';