[simple] checkboxes can get the focusable

Do note that checkboxes in the engine tab are displayed reversed.
See: 3408d061aa/searx/templates/simple/preferences.html (L313)
A checkbox for an engine is checked when the engine is disabled.
This commit is contained in:
Alexandre Flament 2022-02-25 15:46:18 +01:00 committed by Alexandre FLAMENT
parent 0ddcc12474
commit 3d9e48b84e
6 changed files with 220 additions and 168 deletions

View file

@ -13,3 +13,7 @@
} }
} }
} }
input.checkbox-onoff[type="checkbox"]::before {
transition: left 0.25s;
}

View file

@ -96,10 +96,13 @@
--color-toolkit-select-border: #ddd; --color-toolkit-select-border: #ddd;
--color-toolkit-select-background-hover: #bbb; --color-toolkit-select-background-hover: #bbb;
--color-toolkit-input-text-font: #222; --color-toolkit-input-text-font: #222;
--color-toolkit-checkbox-onoff-background: #ddd; --color-toolkit-checkbox-onoff-off-background: #ddd;
--color-toolkit-checkbox-onoff-label-background: #3050ff; --color-toolkit-checkbox-onoff-on-background: #ddd;
--color-toolkit-checkbox-onoff-checked-background: #aaa; --color-toolkit-checkbox-onoff-on-mark-background: #3050ff;
--color-toolkit-checkbox-label-background: #fff; --color-toolkit-checkbox-onoff-on-mark-color: #fff;
--color-toolkit-checkbox-onoff-off-mark-background: #aaa;
--color-toolkit-checkbox-onoff-off-mark-color: #fff;
--color-toolkit-checkbox-label-background: #ddd;
--color-toolkit-checkbox-label-border: #ddd; --color-toolkit-checkbox-label-border: #ddd;
--color-toolkit-checkbox-input-border: #3050ff; --color-toolkit-checkbox-input-border: #3050ff;
--color-toolkit-engine-tooltip-border: #ddd; --color-toolkit-engine-tooltip-border: #ddd;
@ -199,10 +202,13 @@
--color-toolkit-select-border: #555; --color-toolkit-select-border: #555;
--color-toolkit-select-background-hover: #333; --color-toolkit-select-background-hover: #333;
--color-toolkit-input-text-font: #fff; --color-toolkit-input-text-font: #fff;
--color-toolkit-checkbox-onoff-background: #3c3b31; --color-toolkit-checkbox-onoff-off-background: #3c3b31;
--color-toolkit-checkbox-onoff-label-background: #58f; --color-toolkit-checkbox-onoff-on-background: #3c3b31;
--color-toolkit-checkbox-onoff-checked-background: #ddd; --color-toolkit-checkbox-onoff-on-mark-background: #58f;
--color-toolkit-checkbox-label-background: #fff; --color-toolkit-checkbox-onoff-on-mark-color: #222;
--color-toolkit-checkbox-onoff-off-mark-background: #ddd;
--color-toolkit-checkbox-onoff-off-mark-color: #222;
--color-toolkit-checkbox-label-background: #222;
--color-toolkit-checkbox-label-border: #333; --color-toolkit-checkbox-label-border: #333;
--color-toolkit-checkbox-input-border: #58f; --color-toolkit-checkbox-input-border: #58f;
--color-toolkit-engine-tooltip-border: #333; --color-toolkit-engine-tooltip-border: #333;

View file

@ -80,6 +80,55 @@
text-align: center; text-align: center;
} }
.category {
.ltr-margin-right(0.5rem);
label {
border: 2px solid transparent;
padding: 0.2rem 0.4rem;
.rounded-corners-tiny;
}
}
.category input[type="checkbox"]:checked + label {
border: 2px solid var(--color-categories-item-border-selected);
}
table.table_engines {
td {
height: 3.75rem;
}
th.name {
/* stylelint-disable */
label {
cursor: pointer;
}
/* stylelint-enable */
.engine-tooltip {
margin-top: 1.8rem;
.ltr-left(calc((100% - 85em) / 2 + 10em));
max-width: 40rem;
.engine-description {
margin-top: 0.5rem;
}
}
}
.engine-group {
.ltr-text-align-left();
font-weight: normal;
background: var(--color-settings-engine-group-background);
}
.name,
.shortcut {
.ltr-text-align-left();
}
}
table.cookies { table.cookies {
width: 100%; width: 100%;
direction: ltr; direction: ltr;
@ -109,25 +158,6 @@
} }
} }
.category {
.ltr-margin-right(0.5rem);
label {
border: 2px solid transparent;
padding: 0.2rem 0.4rem;
.rounded-corners-tiny;
}
}
.category input[type="checkbox"]:checked + label {
border: 2px solid var(--color-categories-item-border-selected);
}
.name,
.shortcut {
.ltr-text-align-left();
}
.preferences_back { .preferences_back {
background: none repeat scroll 0 0 var(--color-btn-background); background: none repeat scroll 0 0 var(--color-btn-background);
color: var(--color-btn-font); color: var(--color-btn-font);
@ -153,24 +183,6 @@
width: 100%; width: 100%;
} }
} }
th.name {
.engine-tooltip {
margin-top: 1.8rem;
.ltr-left(calc((100% - 85em) / 2 + 10em));
max-width: 40rem;
.engine-description {
margin-top: 0.5rem;
}
}
}
.engine-group {
.ltr-text-align-left();
font-weight: normal;
background: var(--color-settings-engine-group-background);
}
} }
@media screen and (max-width: @tablet) { @media screen and (max-width: @tablet) {

View file

@ -378,64 +378,102 @@ select {
} }
/* -- checkbox-onoff -- */ /* -- checkbox-onoff -- */
@supports (border-radius: 50px) { input.checkbox-onoff[type="checkbox"] {
.checkbox-onoff { -webkit-appearance: none;
display: inline-block; -moz-appearance: none;
width: 40px; appearance: none;
height: 10px;
background: var(--color-toolkit-checkbox-onoff-background);
margin: 8px 1rem;
position: relative;
border-radius: 50px;
label {
display: block;
width: 20px;
height: 20px;
position: absolute;
top: -5px;
cursor: pointer; cursor: pointer;
border-radius: 50px; display: inline-block;
transition: all 0.4s ease; width: 2.5em;
left: 27px; height: 0.7em;
background-color: var(--color-toolkit-checkbox-onoff-label-background); box-shadow: none !important;
margin: 0 16px;
border-radius: 10px;
position: relative;
/* focus & hover */
&:focus,
&:hover {
outline: none;
} }
input[type=checkbox] { &:focus::after {
visibility: hidden; content: "";
position: absolute;
width: 3.5em;
height: 1.65em;
border: 1px solid var(--color-btn-background);
border-radius: 12px;
box-shadow: var(--color-btn-background) 0 0 3px;
z-index: 10000;
top: -0.55em;
left: -0.6em;
}
&:checked + label { &::before {
left: -5px; position: absolute;
background: var(--color-toolkit-checkbox-onoff-checked-background); top: -0.5em;
display: flex;
justify-content: center;
align-items: center;
font-size: 0.75em;
width: 1.875em;
height: 1.875em;
border-radius: 50%;
} }
} }
/* check mark
reversed-checkbox displays unchecked checkedboxes as checked, and vice versa.
see https://github.com/searxng/searxng/blob/3408d061aab9abc6168fec9bbc6deab71b236dac/searx/templates/simple/preferences.html#L313
*/
input.checkbox-onoff[type="checkbox"],
.reversed-checkbox input.checkbox-onoff[type="checkbox"]:checked {
background: var(--color-toolkit-checkbox-onoff-off-background);
&::before {
left: -0.5em;
content: "\2715";
color: var(--color-toolkit-checkbox-onoff-off-mark-color);
background: var(--color-toolkit-checkbox-onoff-off-mark-background);
}
}
input.checkbox-onoff[type="checkbox"]:checked,
.reversed-checkbox input.checkbox-onoff[type="checkbox"] {
background: var(--color-toolkit-checkbox-onoff-on-background);
&::before {
left: calc(100% - 1.5em);
content: "\2713";
color: var(--color-toolkit-checkbox-onoff-on-mark-color);
background: var(--color-toolkit-checkbox-onoff-on-mark-background);
} }
} }
/* -- checkbox -- */ /* -- checkbox -- */
@supports (transform: rotate(-45deg)) { @supports (transform: rotate(-45deg)) {
.checkbox { input[type=checkbox]:not(.checkbox-onoff) {
width: 20px; -webkit-appearance: none;
position: relative; -moz-appearance: none;
margin: 20px auto; appearance: none;
label {
width: 20px; width: 20px;
height: 20px; height: 20px;
cursor: pointer; cursor: pointer;
position: absolute; position: relative;
top: 0; top: 0;
left: 0; left: 0;
background: var(--color-toolkit-checkbox-label-background); border: 2px solid var(--color-toolkit-checkbox-input-border);
.rounded-corners; .rounded-corners(0.3em);
&::after { &::after {
content: ''; content: '';
width: 9px; width: 9px;
height: 5px; height: 5px;
position: absolute; position: absolute;
top: 4px; top: 3px;
left: 4px; left: 2px;
border: 3px solid var(--color-toolkit-checkbox-label-border); border: 3px solid var(--color-toolkit-checkbox-label-border);
border-top: none; border-top: none;
border-right: none; border-right: none;
@ -443,29 +481,25 @@ select {
opacity: 0; opacity: 0;
transform: rotate(-45deg); transform: rotate(-45deg);
} }
}
input[type=checkbox] { &:checked::after {
visibility: hidden;
&:checked + label::after {
border-color: var(--color-toolkit-checkbox-input-border); border-color: var(--color-toolkit-checkbox-input-border);
opacity: 1; opacity: 1;
} }
} }
// disabled : can''t be focused, show only the check mark // disabled : can't be focused, show only the check mark
input[disabled] + label { input[type=checkbox][disabled]:not(.checkbox-onoff) {
border: inherit;
background-color: transparent !important; background-color: transparent !important;
cursor: inherit; cursor: inherit;
} }
// if not checked and possible to checked then display a "light" check mark on hover // if not checked and possible to checked then display a "light" check mark on hover
input:not(:checked):not([readonly]):not([disabled]) + label:hover::after { input.checkbox[type=checkbox]:not(:checked):not([disabled]):not(.checkbox-onoff):hover::after {
opacity: 0.5; opacity: 0.5;
} }
} }
}
@media screen and (max-width: @phone) { @media screen and (max-width: @phone) {
.tabs > label { .tabs > label {

View file

@ -72,19 +72,13 @@
{%- endmacro -%} {%- endmacro -%}
{%- macro checkbox_onoff(name, checked) -%} {%- macro checkbox_onoff(name, checked) -%}
<div class="checkbox-onoff">{{- '' -}} <input type="checkbox" name="{{ name }}" id="{{ name }}" value="None" class="checkbox-onoff" {% if checked %}checked{% endif %} />
<input type="checkbox" value="None" id="{{ name }}" name="{{ name }}" {% if checked %}checked{% endif %}/>{{- '' -}}
<label for="{{ name }}"></label>{{- '' -}}
</div>
{%- endmacro -%} {%- endmacro -%}
{%- macro checkbox(name, checked, readonly, disabled) -%} {%- macro checkbox(name, checked, disabled) -%}
<div class="checkbox">{{- '' -}}
{%- if checked == '?' -%} {%- if checked == '?' -%}
{{ icon_small('warning') }} {{- icon_small('warning') -}}
{%- else -%} {%- else -%}
<input type="checkbox" value="None" id="{{ name }}" name="{{ name }}" {% if checked %}checked{% endif %}{% if readonly %} readonly="readonly" {% endif %}{% if disabled %} disabled="disabled" {% endif %}/>{{- '' -}} <input type="checkbox"{% if name %} name="{{ name }}"{% endif %} value="None"{% if checked %} checked{% endif %}{% if disabled %} disabled{% endif %} />
<label for="{{ name }}"></label>{{- '' -}}
{%- endif -%} {%- endif -%}
</div>
{%- endmacro -%} {%- endmacro -%}

View file

@ -23,13 +23,13 @@
{% if search_engine.about is defined %} {% if search_engine.about is defined %}
{% set about = search_engine.about %} {% set about = search_engine.about %}
<div class="engine-tooltip" role="tooltip">{{- "" -}} <div class="engine-tooltip" role="tooltip">{{- "" -}}
<p class="engine-description"></p> <p class="engine-description"></p>{{- "" -}}
<p><a href="{{about.website}}" rel="noreferrer">{{about.website}}</a></p> <p><a href="{{about.website}}" rel="noreferrer">{{about.website}}</a></p>
{%- if about.wikidata_id -%}<p><a href="https://www.wikidata.org/wiki/{{about.wikidata_id}}" rel="noreferrer">wikidata.org/wiki/{{about.wikidata_id}}</a></p>{%- endif -%} {%- if about.wikidata_id -%}<p><a href="https://www.wikidata.org/wiki/{{about.wikidata_id}}" rel="noreferrer">wikidata.org/wiki/{{about.wikidata_id}}</a></p>{%- endif -%}
{%- if search_engine.enable_http %}<p>{{ icon_big('exclamation-sign', 'No HTTPS') }}{{ _('No HTTPS')}}</p>{% endif -%} {%- if search_engine.enable_http %}<p>{{ icon_big('exclamation-sign', 'No HTTPS') }}{{ _('No HTTPS')}}</p>{% endif -%}
{%- if reliabilities.get(search_engine.name, {}).errors or reliabilities.get(search_engine.name, {}).checker -%} {%- if reliabilities.get(search_engine.name, {}).errors or reliabilities.get(search_engine.name, {}).checker -%}
<a href="{{ url_for('stats', engine=search_engine.name|e) }}" title="{{ _('View error logs and submit a bug report') }}"> <a href="{{ url_for('stats', engine=search_engine.name|e) }}" title="{{ _('View error logs and submit a bug report') }}">
{{ _('View error logs and submit a bug report') }} {{ _('View error logs and submit a bug report') -}}
</a> </a>
{%- endif -%} {%- endif -%}
@ -89,7 +89,7 @@
</div>{{- "" -}} </div>{{- "" -}}
</td> </td>
{%- else -%} {%- else -%}
<td class="{{ label }}"><span>{{ r }}</span></td> <td class="{{ label }}">{% if r %}<span>{{ r }}</span>{% endif %}</td>
{%- endif -%} {%- endif -%}
{%- endmacro -%} {%- endmacro -%}
@ -98,7 +98,7 @@
{% block content %} {% block content %}
<h1>{{ _('Preferences') }}</h1> <h1>{{ _('Preferences') }}</h1>
<form id="search_form" method="post" action="{{ url_for('preferences') }}" autocomplete="off"> <form id="search_form" method="post" action="{{ url_for('preferences') }}" autocomplete="off" class="reversed-checkbox">
{{ tabs_open() }} {{ tabs_open() }}
@ -182,9 +182,9 @@
<legend>{{ _('Interface language') }}</legend> <legend>{{ _('Interface language') }}</legend>
<p class="value"> <p class="value">
<select name='locale'> <select name='locale'>
{% for locale_id,locale_name in locales.items() | sort %} {%- for locale_id,locale_name in locales.items() | sort -%}
<option value="{{ locale_id }}" {% if locale_id == current_locale %}selected="selected"{% endif %}>{{ locale_name }}</option> <option value="{{ locale_id }}" {% if locale_id == current_locale %}selected="selected"{% endif %}>{{ locale_name }}</option>
{% endfor %} {%- endfor -%}
</select> </select>
</p> </p>
<div class="description">{{ _('Change the language of the layout') }}</div> <div class="description">{{ _('Change the language of the layout') }}</div>
@ -290,17 +290,17 @@
<p>{{_('This tab does not show up for search results, but you can search the engines listed here via bangs.')}}</p> <p>{{_('This tab does not show up for search results, but you can search the engines listed here via bangs.')}}</p>
{% endif %} {% endif %}
<div class="scrollx"> <div class="scrollx">
<table class="striped"> <table class="striped table_engines">
<tr> <tr>{{- "" -}}
<th class="engine_checkbox">{{ _("Allow") }}</th> <th class="engine_checkbox">{{ _("Allow") }}</th>{{- "" -}}
<th class="name">{{ _("Engine name") }}</th> <th class="name">{{ _("Engine name") }}</th>{{- "" -}}
<th class="shortcut">{{ _("Shortcut") }}</th> <th class="shortcut">{{ _("Shortcut") }}</th>{{- "" -}}
<th>{{ _("Supports selected language") }}</th> <th>{{ _("Supports selected language") }}</th>{{- "" -}}
<th>{{ _("SafeSearch") }}</th> <th>{{ _("SafeSearch") }}</th>{{- "" -}}
<th>{{ _("Time range") }}</th> <th>{{ _("Time range") }}</th>{{- "" -}}
<th>{{ _("Response time") }}</th> <th>{{ _("Response time") }}</th>{{- "" -}}
<th>{{ _("Max time") }}</th> <th>{{ _("Max time") }}</th>{{- "" -}}
<th>{{ _("Reliability") }}</th> <th>{{ _("Reliability") }}</th>{{- "" -}}
</tr> </tr>
{% for group, engines in engines_by_category[categ] | group_engines_in_tab %} {% for group, engines in engines_by_category[categ] | group_engines_in_tab %}
{% if loop.length > 1 %} {% if loop.length > 1 %}
@ -309,22 +309,24 @@
{% for search_engine in engines %} {% for search_engine in engines %}
{% if not search_engine.private %} {% if not search_engine.private %}
{% set engine_id = 'engine_' + search_engine.name|replace(' ', '_') + '__' + categ|replace(' ', '_') %} {% set engine_id = 'engine_' + search_engine.name|replace(' ', '_') + '__' + categ|replace(' ', '_') %}
<tr> <tr>{{- "" -}}
<td class="engine_checkbox">{{ checkbox_onoff(engine_id, (search_engine.name, categ) in disabled_engines) }}</td> <td>{{ checkbox_onoff(engine_id, (search_engine.name, categ) in disabled_engines) }}</td>{{- "" -}}
<th class="name" data-engine-name="{{ search_engine.name }}">{% if search_engine.enable_http %}{{ icon_big('warning', 'No HTTPS') }}{% endif %} <th class="name" data-engine-name="{{ search_engine.name }}">{% if search_engine.enable_http %}{{ icon_big('warning', 'No HTTPS') }}{% endif -%}
{{ search_engine.name }} <label for="{{ engine_id }}">
{%- if search_engine.about and search_engine.about.language %} {{- search_engine.name -}}
{%- if search_engine.about and search_engine.about.language -%}
({{search_engine.about.language | upper}}) ({{search_engine.about.language | upper}})
{%- endif %} {%- endif -%}
{{ engine_about(search_engine) }} </label>
</th> {{- engine_about(search_engine) -}}
<td class="shortcut">{{ shortcuts[search_engine.name] }}</td> </th>{{- "" -}}
<td>{{ checkbox(engine_id + '_supported_languages', supports[search_engine.name]['supports_selected_language'], true, true) }}</td> <td class="shortcut">{{ shortcuts[search_engine.name] }}</td>{{- "" -}}
<td>{{ checkbox(engine_id + '_safesearch', supports[search_engine.name]['safesearch'], true, true) }}</td> <td>{{ checkbox(None, supports[search_engine.name]['supports_selected_language'], true) }}</td>{{- "" -}}
<td>{{ checkbox(engine_id + '_time_range_support', supports[search_engine.name]['time_range_support'], true, true) }}</td> <td>{{ checkbox(None, supports[search_engine.name]['safesearch'], true) }}</td>{{- "" -}}
{{ engine_time(search_engine.name) }} <td>{{ checkbox(None, supports[search_engine.name]['time_range_support'], true) }}</td>{{- "" -}}
<td class="{{ 'danger' if stats[search_engine.name]['warn_timeout'] else '' }}">{{ search_engine.timeout }}</td> {{- engine_time(search_engine.name) -}}
{{ engine_reliability(search_engine.name) }} <td class="{{ 'danger' if stats[search_engine.name]['warn_timeout'] else '' }}">{{ search_engine.timeout }}</td>{{- "" -}}
{{ engine_reliability(search_engine.name) -}}
</tr> </tr>
{% endif %} {% endif %}
{% endfor %} {% endfor %}
@ -377,20 +379,20 @@
{{ tab_footer() }} {{ tab_footer() }}
{{ tab_header('maintab', 'cookies', _('Cookies')) }} {{ tab_header('maintab', 'cookies', _('Cookies')) }}
<p class="text-muted"> <p class="text-muted">{{- "" -}}
{{ _('This is the list of cookies and their values SearXNG is storing on your computer.') }}<br /> {{- _('This is the list of cookies and their values SearXNG is storing on your computer.') }}<br />{{- "" -}}
{{ _('With that list, you can assess SearXNG transparency.') }}<br /> {{- _('With that list, you can assess SearXNG transparency.') }}<br />{{- "" -}}
</p> </p>
{% if cookies %} {% if cookies %}
<table class="cookies"> <table class="cookies">
<tr> <tr>{{- "" -}}
<th>{{ _('Cookie name') }}</th> <th>{{ _('Cookie name') }}</th>{{- "" -}}
<th>{{ _('Value') }}</th> <th>{{ _('Value') }}</th>{{- "" -}}
</tr> </tr>
{% for cookie in cookies %} {% for cookie in cookies %}
<tr> <tr>{{- "" -}}
<td>{{ cookie }}</td> <td>{{ cookie }}</td>{{- "" -}}
<td>{{ cookies[cookie] }}</td> <td>{{ cookies[cookie] }}</td>{{- "" -}}
</tr> </tr>
{% endfor %} {% endfor %}
</table> </table>