Browse Source

Remove fomantic checkbox module (#30162)

CSS is pretty slim already and the `.ui.toggle.checkbox` sliders on
admin page also still work. The only necessary JS is the one that links
`input` and `label` so that it can be toggled via label. All checkboxes
except the markdown ones render at `--checkbox-size: 16px` now.

<img width="174" alt="Screenshot 2024-03-28 at 22 15 10"
src="https://github.com/go-gitea/gitea/assets/115237/3455c1bb-166b-47e4-9847-2d20dd1f04db">

<img width="499" alt="Screenshot 2024-03-28 at 21 00 07"
src="https://github.com/go-gitea/gitea/assets/115237/412be2b3-d5a0-478a-b17b-43e6bc12e8ce">

<img width="83" alt="Screenshot 2024-03-28 at 22 14 34"
src="https://github.com/go-gitea/gitea/assets/115237/d8c89838-a420-4723-8c49-89405bb39474">

---------

Co-authored-by: delvh <dev.lh@web.de>
pull/30140/head
silverwind 4 weeks ago
parent
commit
8fd15990c5
No account linked to committer's email address

+ 2
- 2
templates/admin/config_settings.tmpl View File

@@ -7,14 +7,14 @@
<dt>{{ctx.Locale.Tr "admin.config.disable_gravatar"}}</dt>
<dd>
<div class="ui toggle checkbox" data-tooltip-content="{{ctx.Locale.Tr "admin.config.disable_gravatar"}}">
<input type="checkbox" data-config-dyn-key="picture.disable_gravatar" {{if .SystemConfig.Picture.DisableGravatar.Value ctx}}checked{{end}}>
<input type="checkbox" data-config-dyn-key="picture.disable_gravatar" {{if .SystemConfig.Picture.DisableGravatar.Value ctx}}checked{{end}}><label></label>
</div>
</dd>
<div class="divider"></div>
<dt>{{ctx.Locale.Tr "admin.config.enable_federated_avatar"}}</dt>
<dd>
<div class="ui toggle checkbox" data-tooltip-content="{{ctx.Locale.Tr "admin.config.enable_federated_avatar"}}">
<input type="checkbox" data-config-dyn-key="picture.enable_federated_avatar" {{if .SystemConfig.Picture.EnableFederatedAvatar.Value ctx}}checked{{end}}>
<input type="checkbox" data-config-dyn-key="picture.enable_federated_avatar" {{if .SystemConfig.Picture.EnableFederatedAvatar.Value ctx}}checked{{end}}><label></label>
</div>
</dd>
</dl>

+ 1
- 1
templates/repo/issue/view_content/sidebar.tmpl View File

@@ -677,7 +677,7 @@
{{if and (not (eq .Issue.PullRequest.HeadRepo.FullName .Issue.PullRequest.BaseRepo.FullName)) .CanWriteToHeadRepo}}
<div class="divider"></div>
<div class="inline field">
<div class="ui checkbox" id="allow-edits-from-maintainers"
<div class="ui checkbox small-loading-icon" id="allow-edits-from-maintainers"
data-url="{{.Issue.Link}}"
data-tooltip-content="{{ctx.Locale.Tr "repo.pulls.allow_edits_from_maintainers_desc"}}"
data-prompt-error="{{ctx.Locale.Tr "repo.pulls.allow_edits_from_maintainers_err"}}"

+ 1
- 0
web_src/css/base.css View File

@@ -23,6 +23,7 @@
--height-loading: 16rem;
--min-height-textarea: 132px; /* padding + 6 lines + border = calc(1.57142em + 6lh + 2px), but lh is not fully supported */
--tab-size: 4;
--checkbox-size: 16px; /* height and width of checkbox and radio inputs */
}

:root * {

+ 5
- 54
web_src/css/form.css View File

@@ -32,10 +32,7 @@ textarea,
.ui.form input[type="text"],
.ui.form input[type="time"],
.ui.form input[type="url"],
.ui.selection.dropdown,
.ui.checkbox label::before,
.ui.checkbox input:checked ~ label::before,
.ui.checkbox input:not([type="radio"]):indeterminate ~ label::before {
.ui.selection.dropdown {
background: var(--color-input-background);
border-color: var(--color-input-border);
color: var(--color-input-text);
@@ -63,12 +60,7 @@ textarea:hover,
.ui.form input[type="text"]:hover,
.ui.form input[type="time"]:hover,
.ui.form input[type="url"]:hover,
.ui.selection.dropdown:hover,
.ui.checkbox label:hover::before,
.ui.checkbox label:active::before,
.ui.radio.checkbox label::after,
.ui.radio.checkbox input:focus ~ label::before,
.ui.radio.checkbox input:checked ~ label::before {
.ui.selection.dropdown:hover {
background: var(--color-input-background);
border-color: var(--color-input-border-hover);
color: var(--color-input-text);
@@ -91,11 +83,7 @@ textarea:focus,
.ui.form input[type="text"]:focus,
.ui.form input[type="time"]:focus,
.ui.form input[type="url"]:focus,
.ui.selection.dropdown:focus,
.ui.checkbox input:focus ~ label::before,
.ui.checkbox input:not([type="radio"]):indeterminate:focus ~ label::before,
.ui.checkbox input:checked:focus ~ label::before,
.ui.radio.checkbox input:focus:checked ~ label::before {
.ui.selection.dropdown:focus {
background: var(--color-input-background);
border-color: var(--color-primary);
color: var(--color-input-text);
@@ -106,58 +94,21 @@ textarea:focus,
.ui.form .inline.fields .field > label,
.ui.form .inline.fields .field > p,
.ui.form .inline.field > label,
.ui.form .inline.field > p,
.ui.checkbox label,
.ui.checkbox + label,
.ui.checkbox label:hover,
.ui.checkbox + label:hover,
.ui.checkbox input:focus ~ label,
.ui.checkbox input:active ~ label {
.ui.form .inline.field > p {
color: var(--color-text);
}

.ui.form .required.fields:not(.grouped) > .field > label::after,
.ui.form .required.fields.grouped > label::after,
.ui.form .required.field > label::after,
.ui.form .required.fields:not(.grouped) > .field > .checkbox::after,
.ui.form .required.field > .checkbox::after,
.ui.form label.required::after {
color: var(--color-red);
}

.ui.input,
.ui.checkbox input:focus ~ label::after,
.ui.checkbox input:checked ~ label::after,
.ui.checkbox label:active::after,
.ui.checkbox input:not([type="radio"]):indeterminate ~ label::after,
.ui.checkbox input:not([type="radio"]):indeterminate:focus ~ label::after,
.ui.checkbox input:checked:focus ~ label::after,
.ui.disabled.checkbox label,
.ui.checkbox input[disabled] ~ label {
.ui.input {
color: var(--color-input-text);
}

.ui.radio.checkbox input:focus ~ label::after,
.ui.radio.checkbox input:checked ~ label::after,
.ui.radio.checkbox input:focus:checked ~ label::after {
background: var(--color-input-text);
}

.ui.toggle.checkbox label::before {
background: var(--color-input-toggle-background);
}

.ui.toggle.checkbox label,
.ui.toggle.checkbox input:checked ~ label,
.ui.toggle.checkbox input:focus:checked ~ label {
color: var(--color-text) !important;
}

.ui.toggle.checkbox input:checked ~ label::before,
.ui.toggle.checkbox input:focus:checked ~ label::before {
background: var(--color-primary) !important;
}

/* match <select> padding to <input> */
.ui.form select {
padding: 0.67857143em 1em;

+ 1
- 0
web_src/css/index.css View File

@@ -12,6 +12,7 @@
@import "./modules/message.css";
@import "./modules/table.css";
@import "./modules/card.css";
@import "./modules/checkbox.css";
@import "./modules/modal.css";

@import "./modules/select.css";

+ 0
- 1
web_src/css/modules/animations.css View File

@@ -6,7 +6,6 @@
.is-loading {
pointer-events: none !important;
position: relative !important;
overflow: hidden !important;
}

.is-loading > * {

+ 120
- 0
web_src/css/modules/checkbox.css View File

@@ -0,0 +1,120 @@
/* based on Fomantic UI checkbox module, with just the parts extracted that we use. If you find any
unused rules here after refactoring, please remove them. */

input[type="checkbox"],
input[type="radio"] {
width: var(--checkbox-size);
height: var(--checkbox-size);
}

.ui.checkbox {
position: relative;
display: inline-block;
vertical-align: baseline;
min-height: var(--checkbox-size);
line-height: var(--checkbox-size);
min-width: var(--checkbox-size);
padding: 1px;
}

.ui.checkbox input[type="checkbox"],
.ui.checkbox input[type="radio"] {
position: absolute;
top: 0;
left: 0;
width: var(--checkbox-size);
height: var(--checkbox-size);
}

.ui.checkbox input[type="checkbox"]:enabled,
.ui.checkbox input[type="radio"]:enabled,
.ui.checkbox label:enabled {
cursor: pointer;
}

.ui.checkbox label {
cursor: auto;
position: relative;
display: block;
user-select: none;
}

.ui.checkbox label,
.ui.radio.checkbox label {
padding-left: 1.85714em;
}

.ui.checkbox + label {
vertical-align: middle;
}

.ui.disabled.checkbox label,
.ui.checkbox input[disabled] ~ label {
cursor: default !important;
opacity: 0.5;
pointer-events: none;
}

.ui.radio.checkbox {
min-height: var(--checkbox-size);
}

/* "switch" styled checkbox */

.ui.toggle.checkbox {
min-height: 1.5rem;
}
.ui.toggle.checkbox input {
width: 3.5rem;
height: 1.5rem;
opacity: 0;
z-index: 3;
}
.ui.toggle.checkbox label {
min-height: 1.5rem;
padding-left: 4.5rem;
padding-top: 0.15em;
}
.ui.toggle.checkbox label::before {
display: block;
position: absolute;
content: "";
z-index: 1;
top: 0;
width: 3.5rem;
height: 1.5rem;
border-radius: 500rem;
left: 0;
}
.ui.toggle.checkbox label::after {
background: var(--color-white);
position: absolute;
content: "";
opacity: 1;
z-index: 2;
width: 1.5rem;
height: 1.5rem;
top: 0;
left: 0;
border-radius: 500rem;
transition: background 0.3s ease, left 0.3s ease;
}
.ui.toggle.checkbox input ~ label::after {
left: -0.05rem;
}
.ui.toggle.checkbox input:checked ~ label::after {
left: 2.15rem;
}
.ui.toggle.checkbox input:focus ~ label::before,
.ui.toggle.checkbox label::before {
background: var(--color-input-toggle-background);
}
.ui.toggle.checkbox label,
.ui.toggle.checkbox input:checked ~ label,
.ui.toggle.checkbox input:focus:checked ~ label {
color: var(--color-text) !important;
}
.ui.toggle.checkbox input:checked ~ label::before,
.ui.toggle.checkbox input:focus:checked ~ label::before {
background: var(--color-primary) !important;
}

+ 0
- 4
web_src/css/org.css View File

@@ -89,10 +89,6 @@
text-align: center;
}

.organization.options input {
min-width: 300px;
}

.page-content.organization .org-avatar {
margin-right: 15px;
}

+ 1
- 0
web_src/css/repo/issue-list.css View File

@@ -9,6 +9,7 @@

.issue-list-toolbar-left {
display: flex;
align-items: center;
}

.issue-list-toolbar-right .filter.menu {

+ 0
- 709
web_src/fomantic/build/semantic.css View File

@@ -2323,715 +2323,6 @@
Theme Overrides
*******************************/

/*******************************
Site Overrides
*******************************/
/*!
* # Fomantic-UI - Checkbox
* http://github.com/fomantic/Fomantic-UI/
*
*
* Released under the MIT license
* http://opensource.org/licenses/MIT
*
*/

/*******************************
Checkbox
*******************************/

/*--------------
Content
---------------*/

.ui.checkbox {
position: relative;
display: inline-block;
backface-visibility: hidden;
outline: none;
vertical-align: baseline;
font-style: normal;
min-height: 17px;
font-size: 1em;
line-height: 17px;
min-width: 17px;
}

/* HTML Checkbox */

.ui.checkbox input[type="checkbox"],
.ui.checkbox input[type="radio"] {
cursor: pointer;
position: absolute;
top: 0;
left: 0;
opacity: 0 !important;
outline: none;
z-index: 3;
width: 17px;
height: 17px;
}

.ui.checkbox label {
cursor: auto;
position: relative;
display: block;
padding-left: 1.85714em;
outline: none;
font-size: 1em;
}

.ui.checkbox label:before {
position: absolute;
top: 0;
left: 0;
width: 17px;
height: 17px;
content: '';
background: #FFFFFF;
border-radius: 0.21428571rem;
transition: border 0.1s ease, opacity 0.1s ease, transform 0.1s ease, box-shadow 0.1s ease;
border: 1px solid #D4D4D5;
}

/*--------------
Checkmark
---------------*/

.ui.checkbox label:after {
position: absolute;
font-size: 14px;
top: 0;
left: 0;
width: 17px;
height: 17px;
text-align: center;
opacity: 0;
color: rgba(0, 0, 0, 0.87);
transition: border 0.1s ease, opacity 0.1s ease, transform 0.1s ease, box-shadow 0.1s ease;
}

/*--------------
Label
---------------*/

/* Inside */

.ui.checkbox label,
.ui.checkbox + label {
color: rgba(0, 0, 0, 0.87);
transition: color 0.1s ease;
}

/* Outside */

.ui.checkbox + label {
vertical-align: middle;
}

/*******************************
States
*******************************/

/*--------------
Hover
---------------*/

.ui.checkbox label:hover::before {
background: #FFFFFF;
border-color: rgba(34, 36, 38, 0.35);
}

.ui.checkbox label:hover,
.ui.checkbox + label:hover {
color: rgba(0, 0, 0, 0.8);
}

/*--------------
Down
---------------*/

.ui.checkbox label:active::before {
background: #F9FAFB;
border-color: rgba(34, 36, 38, 0.35);
}

.ui.checkbox label:active::after {
color: rgba(0, 0, 0, 0.95);
}

.ui.checkbox input:active ~ label {
color: rgba(0, 0, 0, 0.95);
}

/*--------------
Focus
---------------*/

.ui.checkbox input:focus ~ label:before {
background: #FFFFFF;
border-color: #96C8DA;
}

.ui.checkbox input:focus ~ label:after {
color: rgba(0, 0, 0, 0.95);
}

.ui.checkbox input:focus ~ label {
color: rgba(0, 0, 0, 0.95);
}

/*--------------
Active
---------------*/

.ui.checkbox input:checked ~ label:before {
background: #FFFFFF;
border-color: rgba(34, 36, 38, 0.35);
}

.ui.checkbox input:checked ~ label:after {
opacity: 1;
color: rgba(0, 0, 0, 0.95);
}

/*--------------
Indeterminate
---------------*/

.ui.checkbox input:not([type=radio]):indeterminate ~ label:before {
background: #FFFFFF;
border-color: rgba(34, 36, 38, 0.35);
}

.ui.checkbox input:not([type=radio]):indeterminate ~ label:after {
opacity: 1;
color: rgba(0, 0, 0, 0.95);
}

.ui.indeterminate.toggle.checkbox input:not([type=radio]):indeterminate ~ label:before {
background: rgba(0, 0, 0, 0.15);
}

.ui.indeterminate.toggle.checkbox input:not([type=radio]) ~ label:after {
left: 1.075rem;
}

/*--------------
Active Focus
---------------*/

.ui.checkbox input:not([type=radio]):indeterminate:focus ~ label:before,
.ui.checkbox input:checked:focus ~ label:before {
background: #FFFFFF;
border-color: #96C8DA;
}

.ui.checkbox input:not([type=radio]):indeterminate:focus ~ label:after,
.ui.checkbox input:checked:focus ~ label:after {
color: rgba(0, 0, 0, 0.95);
}

/*--------------
Read-Only
---------------*/

.ui.read-only.checkbox,
.ui.read-only.checkbox label {
cursor: default;
}

/*--------------
Disabled
---------------*/

.ui.disabled.checkbox label,
.ui.checkbox input[disabled] ~ label {
cursor: default !important;
opacity: 0.5;
color: #000000;
pointer-events: none;
}

/*--------------
Hidden
---------------*/

/* Initialized checkbox moves input below element
to prevent manually triggering */

.ui.checkbox input.hidden {
z-index: -1;
}

/* Selectable Label */

.ui.checkbox input.hidden + label {
cursor: pointer;
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
}

/*******************************
Types
*******************************/

/*--------------
Radio
---------------*/

.ui.radio.checkbox {
min-height: 15px;
}

.ui.radio.checkbox label {
padding-left: 1.85714em;
}

/* Box */

.ui.radio.checkbox label:before {
content: '';
transform: none;
width: 15px;
height: 15px;
border-radius: 500rem;
top: 1px;
left: 0;
}

/* Bullet */

.ui.radio.checkbox label:after {
border: none;
content: '' !important;
line-height: 15px;
top: 1px;
left: 0;
width: 15px;
height: 15px;
border-radius: 500rem;
transform: scale(0.46666667);
background-color: rgba(0, 0, 0, 0.87);
}

/* Focus */

.ui.radio.checkbox input:focus ~ label:before {
background-color: #FFFFFF;
}

.ui.radio.checkbox input:focus ~ label:after {
background-color: rgba(0, 0, 0, 0.95);
}

/* Indeterminate */

.ui.radio.checkbox input:indeterminate ~ label:after {
opacity: 0;
}

/* Active */

.ui.radio.checkbox input:checked ~ label:before {
background-color: #FFFFFF;
}

.ui.radio.checkbox input:checked ~ label:after {
background-color: rgba(0, 0, 0, 0.95);
}

/* Active Focus */

.ui.radio.checkbox input:focus:checked ~ label:before {
background-color: #FFFFFF;
}

.ui.radio.checkbox input:focus:checked ~ label:after {
background-color: rgba(0, 0, 0, 0.95);
}

/*--------------
Slider
---------------*/

.ui.slider.checkbox {
min-height: 1.25rem;
}

/* Input */

.ui.slider.checkbox input {
width: 3.5rem;
height: 1.25rem;
}

/* Label */

.ui.slider.checkbox label {
padding-left: 4.5rem;
line-height: 1rem;
color: rgba(0, 0, 0, 0.4);
}

/* Line */

.ui.slider.checkbox label:before {
display: block;
position: absolute;
content: '';
transform: none;
border: none !important;
left: 0;
z-index: 1;
top: 0.4rem;
background-color: rgba(0, 0, 0, 0.05);
width: 3.5rem;
height: 0.21428571rem;
border-radius: 500rem;
transition: background 0.3s ease;
}

/* Handle */

.ui.slider.checkbox label:after {
background: #FFFFFF linear-gradient(transparent, rgba(0, 0, 0, 0.05));
position: absolute;
content: '' !important;
opacity: 1;
z-index: 2;
border: none;
box-shadow: 0 1px 2px 0 rgba(34, 36, 38, 0.15), 0 0 0 1px rgba(34, 36, 38, 0.15) inset;
width: 1.5rem;
height: 1.5rem;
top: -0.25rem;
left: 0;
transform: none;
border-radius: 500rem;
transition: left 0.3s ease;
}

/* Focus */

.ui.slider.checkbox input:focus ~ label:before {
background-color: rgba(0, 0, 0, 0.15);
border: none;
}

/* Hover */

.ui.slider.checkbox label:hover {
color: rgba(0, 0, 0, 0.8);
}

.ui.slider.checkbox label:hover::before {
background: rgba(0, 0, 0, 0.15);
}

/* Active */

.ui.slider.checkbox input:checked ~ label {
color: rgba(0, 0, 0, 0.95) !important;
}

.ui.slider.checkbox input:checked ~ label:before {
background-color: #545454 !important;
}

.ui.slider.checkbox input:checked ~ label:after {
left: 2rem;
}

/* Active Focus */

.ui.slider.checkbox input:focus:checked ~ label {
color: rgba(0, 0, 0, 0.95) !important;
}

.ui.slider.checkbox input:focus:checked ~ label:before {
background-color: #000000 !important;
}

/*--------------
Toggle
---------------*/

.ui.toggle.checkbox {
min-height: 1.5rem;
}

/* Input */

.ui.toggle.checkbox input {
width: 3.5rem;
height: 1.5rem;
}

/* Label */

.ui.toggle.checkbox label {
min-height: 1.5rem;
padding-left: 4.5rem;
color: rgba(0, 0, 0, 0.87);
}

.ui.toggle.checkbox label {
padding-top: 0.15em;
}

/* Switch */

.ui.toggle.checkbox label:before {
display: block;
position: absolute;
content: '';
z-index: 1;
transform: none;
border: none;
top: 0;
background: rgba(0, 0, 0, 0.05);
box-shadow: none;
width: 3.5rem;
height: 1.5rem;
border-radius: 500rem;
}

/* Handle */

.ui.toggle.checkbox label:after {
background: #FFFFFF linear-gradient(transparent, rgba(0, 0, 0, 0.05));
position: absolute;
content: '' !important;
opacity: 1;
z-index: 2;
border: none;
box-shadow: 0 1px 2px 0 rgba(34, 36, 38, 0.15), 0 0 0 1px rgba(34, 36, 38, 0.15) inset;
width: 1.5rem;
height: 1.5rem;
top: 0;
left: 0;
border-radius: 500rem;
transition: background 0.3s ease, left 0.3s ease;
}

.ui.toggle.checkbox input ~ label:after {
left: -0.05rem;
box-shadow: 0 1px 2px 0 rgba(34, 36, 38, 0.15), 0 0 0 1px rgba(34, 36, 38, 0.15) inset;
}

/* Focus */

.ui.toggle.checkbox input:focus ~ label:before {
background-color: rgba(0, 0, 0, 0.15);
border: none;
}

/* Hover */

.ui.toggle.checkbox label:hover::before {
background-color: rgba(0, 0, 0, 0.15);
border: none;
}

/* Active */

.ui.toggle.checkbox input:checked ~ label {
color: rgba(0, 0, 0, 0.95) !important;
}

.ui.toggle.checkbox input:checked ~ label:before {
background-color: #2185D0 !important;
}

.ui.toggle.checkbox input:checked ~ label:after {
left: 2.15rem;
box-shadow: 0 1px 2px 0 rgba(34, 36, 38, 0.15), 0 0 0 1px rgba(34, 36, 38, 0.15) inset;
}

/* Active Focus */

.ui.toggle.checkbox input:focus:checked ~ label {
color: rgba(0, 0, 0, 0.95) !important;
}

.ui.toggle.checkbox input:focus:checked ~ label:before {
background-color: #0d71bb !important;
}

/*******************************
Variations
*******************************/

/*--------------
Fitted
---------------*/

.ui.fitted.checkbox label {
padding-left: 0 !important;
}

.ui.fitted.toggle.checkbox {
width: 3.5rem;
}

.ui.fitted.slider.checkbox {
width: 3.5rem;
}

/*--------------------
Size
---------------------*/

.ui.mini.checkbox {
font-size: 0.78571429em;
}

.ui.tiny.checkbox {
font-size: 0.85714286em;
}

.ui.small.checkbox {
font-size: 0.92857143em;
}

.ui.large.checkbox {
font-size: 1.14285714em;
}

.ui.large.form .checkbox:not(.slider):not(.toggle):not(.radio) label:after,
.ui.large.checkbox:not(.slider):not(.toggle):not(.radio) label:after,
.ui.large.form .checkbox:not(.slider):not(.toggle):not(.radio) label:before,
.ui.large.checkbox:not(.slider):not(.toggle):not(.radio) label:before {
transform: scale(1.14285714);
transform-origin: left;
}

.ui.large.form .checkbox.radio label:before,
.ui.large.checkbox.radio label:before {
transform: scale(1.14285714);
transform-origin: left;
}

.ui.large.form .checkbox.radio label:after,
.ui.large.checkbox.radio label:after {
transform: scale(0.57142857);
transform-origin: left;
left: 0.33571429em;
}

.ui.big.checkbox {
font-size: 1.28571429em;
}

.ui.big.form .checkbox:not(.slider):not(.toggle):not(.radio) label:after,
.ui.big.checkbox:not(.slider):not(.toggle):not(.radio) label:after,
.ui.big.form .checkbox:not(.slider):not(.toggle):not(.radio) label:before,
.ui.big.checkbox:not(.slider):not(.toggle):not(.radio) label:before {
transform: scale(1.28571429);
transform-origin: left;
}

.ui.big.form .checkbox.radio label:before,
.ui.big.checkbox.radio label:before {
transform: scale(1.28571429);
transform-origin: left;
}

.ui.big.form .checkbox.radio label:after,
.ui.big.checkbox.radio label:after {
transform: scale(0.64285714);
transform-origin: left;
left: 0.37142857em;
}

.ui.huge.checkbox {
font-size: 1.42857143em;
}

.ui.huge.form .checkbox:not(.slider):not(.toggle):not(.radio) label:after,
.ui.huge.checkbox:not(.slider):not(.toggle):not(.radio) label:after,
.ui.huge.form .checkbox:not(.slider):not(.toggle):not(.radio) label:before,
.ui.huge.checkbox:not(.slider):not(.toggle):not(.radio) label:before {
transform: scale(1.42857143);
transform-origin: left;
}

.ui.huge.form .checkbox.radio label:before,
.ui.huge.checkbox.radio label:before {
transform: scale(1.42857143);
transform-origin: left;
}

.ui.huge.form .checkbox.radio label:after,
.ui.huge.checkbox.radio label:after {
transform: scale(0.71428571);
transform-origin: left;
left: 0.40714286em;
}

.ui.massive.checkbox {
font-size: 1.71428571em;
}

.ui.massive.form .checkbox:not(.slider):not(.toggle):not(.radio) label:after,
.ui.massive.checkbox:not(.slider):not(.toggle):not(.radio) label:after,
.ui.massive.form .checkbox:not(.slider):not(.toggle):not(.radio) label:before,
.ui.massive.checkbox:not(.slider):not(.toggle):not(.radio) label:before {
transform: scale(1.71428571);
transform-origin: left;
}

.ui.massive.form .checkbox.radio label:before,
.ui.massive.checkbox.radio label:before {
transform: scale(1.71428571);
transform-origin: left;
}

.ui.massive.form .checkbox.radio label:after,
.ui.massive.checkbox.radio label:after {
transform: scale(0.85714286);
transform-origin: left;
left: 0.47857143em;
}

/*******************************
Theme Overrides
*******************************/

@font-face {
font-family: 'Checkbox';
src: url(data:application/x-font-ttf;charset=utf-8;base64,AAEAAAALAIAAAwAwT1MvMg8SBD8AAAC8AAAAYGNtYXAYVtCJAAABHAAAAFRnYXNwAAAAEAAAAXAAAAAIZ2x5Zn4huwUAAAF4AAABYGhlYWQGPe1ZAAAC2AAAADZoaGVhB30DyAAAAxAAAAAkaG10eBBKAEUAAAM0AAAAHGxvY2EAmgESAAADUAAAABBtYXhwAAkALwAAA2AAAAAgbmFtZSC8IugAAAOAAAABknBvc3QAAwAAAAAFFAAAACAAAwMTAZAABQAAApkCzAAAAI8CmQLMAAAB6wAzAQkAAAAAAAAAAAAAAAAAAAABEAAAAAAAAAAAAAAAAAAAAABAAADoAgPA/8AAQAPAAEAAAAABAAAAAAAAAAAAAAAgAAAAAAADAAAAAwAAABwAAQADAAAAHAADAAEAAAAcAAQAOAAAAAoACAACAAIAAQAg6AL//f//AAAAAAAg6AD//f//AAH/4xgEAAMAAQAAAAAAAAAAAAAAAQAB//8ADwABAAAAAAAAAAAAAgAANzkBAAAAAAEAAAAAAAAAAAACAAA3OQEAAAAAAQAAAAAAAAAAAAIAADc5AQAAAAABAEUAUQO7AvgAGgAAARQHAQYjIicBJjU0PwE2MzIfAQE2MzIfARYVA7sQ/hQQFhcQ/uMQEE4QFxcQqAF2EBcXEE4QAnMWEP4UEBABHRAXFhBOEBCoAXcQEE4QFwAAAAABAAABbgMlAkkAFAAAARUUBwYjISInJj0BNDc2MyEyFxYVAyUQEBf9SRcQEBAQFwK3FxAQAhJtFxAQEBAXbRcQEBAQFwAAAAABAAAASQMlA24ALAAAARUUBwYrARUUBwYrASInJj0BIyInJj0BNDc2OwE1NDc2OwEyFxYdATMyFxYVAyUQEBfuEBAXbhYQEO4XEBAQEBfuEBAWbhcQEO4XEBACEm0XEBDuFxAQEBAX7hAQF20XEBDuFxAQEBAX7hAQFwAAAQAAAAIAAHRSzT9fDzz1AAsEAAAAAADRsdR3AAAAANGx1HcAAAAAA7sDbgAAAAgAAgAAAAAAAAABAAADwP/AAAAEAAAAAAADuwABAAAAAAAAAAAAAAAAAAAABwQAAAAAAAAAAAAAAAIAAAAEAABFAyUAAAMlAAAAAAAAAAoAFAAeAE4AcgCwAAEAAAAHAC0AAQAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAOAK4AAQAAAAAAAQAIAAAAAQAAAAAAAgAHAGkAAQAAAAAAAwAIADkAAQAAAAAABAAIAH4AAQAAAAAABQALABgAAQAAAAAABgAIAFEAAQAAAAAACgAaAJYAAwABBAkAAQAQAAgAAwABBAkAAgAOAHAAAwABBAkAAwAQAEEAAwABBAkABAAQAIYAAwABBAkABQAWACMAAwABBAkABgAQAFkAAwABBAkACgA0ALBDaGVja2JveABDAGgAZQBjAGsAYgBvAHhWZXJzaW9uIDIuMABWAGUAcgBzAGkAbwBuACAAMgAuADBDaGVja2JveABDAGgAZQBjAGsAYgBvAHhDaGVja2JveABDAGgAZQBjAGsAYgBvAHhSZWd1bGFyAFIAZQBnAHUAbABhAHJDaGVja2JveABDAGgAZQBjAGsAYgBvAHhGb250IGdlbmVyYXRlZCBieSBJY29Nb29uLgBGAG8AbgB0ACAAZwBlAG4AZQByAGEAdABlAGQAIABiAHkAIABJAGMAbwBNAG8AbwBuAC4AAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA) format('truetype');
}

/* Checkmark */

.ui.checkbox label:after,
.ui.checkbox .box:after {
font-family: 'Checkbox';
}

/* Checked */

.ui.checkbox input:checked ~ .box:after,
.ui.checkbox input:checked ~ label:after {
content: '\e800';
}

/* Indeterminate */

.ui.checkbox input:indeterminate ~ .box:after,
.ui.checkbox input:indeterminate ~ label:after {
font-size: 12px;
content: '\e801';
}

/* UTF Reference
.check:before { content: '\e800'; }
.dash:before { content: '\e801'; }
.plus:before { content: '\e802'; }
*/

/*******************************
Site Overrides
*******************************/

+ 0
- 877
web_src/fomantic/build/semantic.js View File

@@ -1184,883 +1184,6 @@ $.api.settings = {



})( jQuery, window, document );

/*!
* # Fomantic-UI - Checkbox
* http://github.com/fomantic/Fomantic-UI/
*
*
* Released under the MIT license
* http://opensource.org/licenses/MIT
*
*/

;(function ($, window, document, undefined) {

'use strict';

$.isFunction = $.isFunction || function(obj) {
return typeof obj === "function" && typeof obj.nodeType !== "number";
};

window = (typeof window != 'undefined' && window.Math == Math)
? window
: (typeof self != 'undefined' && self.Math == Math)
? self
: Function('return this')()
;

$.fn.checkbox = function(parameters) {
var
$allModules = $(this),
moduleSelector = $allModules.selector || '',

time = new Date().getTime(),
performance = [],

query = arguments[0],
methodInvoked = (typeof query == 'string'),
queryArguments = [].slice.call(arguments, 1),
returnedValue
;

$allModules
.each(function() {
var
settings = $.extend(true, {}, $.fn.checkbox.settings, parameters),

className = settings.className,
namespace = settings.namespace,
selector = settings.selector,
error = settings.error,

eventNamespace = '.' + namespace,
moduleNamespace = 'module-' + namespace,

$module = $(this),
$label = $(this).children(selector.label),
$input = $(this).children(selector.input),
input = $input[0],

initialLoad = false,
shortcutPressed = false,
instance = $module.data(moduleNamespace),

observer,
element = this,
module
;

module = {

initialize: function() {
module.verbose('Initializing checkbox', settings);

module.create.label();
module.bind.events();

module.set.tabbable();
module.hide.input();

module.observeChanges();
module.instantiate();
module.setup();
},

instantiate: function() {
module.verbose('Storing instance of module', module);
instance = module;
$module
.data(moduleNamespace, module)
;
},

destroy: function() {
module.verbose('Destroying module');
module.unbind.events();
module.show.input();
$module.removeData(moduleNamespace);
},

fix: {
reference: function() {
if( $module.is(selector.input) ) {
module.debug('Behavior called on <input> adjusting invoked element');
$module = $module.closest(selector.checkbox);
module.refresh();
}
}
},

setup: function() {
module.set.initialLoad();
if( module.is.indeterminate() ) {
module.debug('Initial value is indeterminate');
module.indeterminate();
}
else if( module.is.checked() ) {
module.debug('Initial value is checked');
module.check();
}
else {
module.debug('Initial value is unchecked');
module.uncheck();
}
module.remove.initialLoad();
},

refresh: function() {
$label = $module.children(selector.label);
$input = $module.children(selector.input);
input = $input[0];
},

hide: {
input: function() {
module.verbose('Modifying <input> z-index to be unselectable');
$input.addClass(className.hidden);
}
},
show: {
input: function() {
module.verbose('Modifying <input> z-index to be selectable');
$input.removeClass(className.hidden);
}
},

observeChanges: function() {
if('MutationObserver' in window) {
observer = new MutationObserver(function(mutations) {
module.debug('DOM tree modified, updating selector cache');
module.refresh();
});
observer.observe(element, {
childList : true,
subtree : true
});
module.debug('Setting up mutation observer', observer);
}
},

attachEvents: function(selector, event) {
var
$element = $(selector)
;
event = $.isFunction(module[event])
? module[event]
: module.toggle
;
if($element.length > 0) {
module.debug('Attaching checkbox events to element', selector, event);
$element
.on('click' + eventNamespace, event)
;
}
else {
module.error(error.notFound);
}
},

preventDefaultOnInputTarget: function() {
if(typeof event !== 'undefined' && event !== null && $(event.target).is(selector.input)) {
module.verbose('Preventing default check action after manual check action');
event.preventDefault();
}
},

event: {
change: function(event) {
if( !module.should.ignoreCallbacks() ) {
settings.onChange.call(input);
}
},
click: function(event) {
var
$target = $(event.target)
;
if( $target.is(selector.input) ) {
module.verbose('Using default check action on initialized checkbox');
return;
}
if( $target.is(selector.link) ) {
module.debug('Clicking link inside checkbox, skipping toggle');
return;
}
module.toggle();
$input.focus();
event.preventDefault();
},
keydown: function(event) {
var
key = event.which,
keyCode = {
enter : 13,
space : 32,
escape : 27,
left : 37,
up : 38,
right : 39,
down : 40
}
;

var r = module.get.radios(),
rIndex = r.index($module),
rLen = r.length,
checkIndex = false;

if(key == keyCode.left || key == keyCode.up) {
checkIndex = (rIndex === 0 ? rLen : rIndex) - 1;
} else if(key == keyCode.right || key == keyCode.down) {
checkIndex = rIndex === rLen-1 ? 0 : rIndex+1;
}

if (!module.should.ignoreCallbacks() && checkIndex !== false) {
if(settings.beforeUnchecked.apply(input)===false) {
module.verbose('Option not allowed to be unchecked, cancelling key navigation');
return false;
}
if (settings.beforeChecked.apply($(r[checkIndex]).children(selector.input)[0])===false) {
module.verbose('Next option should not allow check, cancelling key navigation');
return false;
}
}

if(key == keyCode.escape) {
module.verbose('Escape key pressed blurring field');
$input.blur();
shortcutPressed = true;
}
else if(!event.ctrlKey && ( key == keyCode.space || (key == keyCode.enter && settings.enableEnterKey)) ) {
module.verbose('Enter/space key pressed, toggling checkbox');
module.toggle();
shortcutPressed = true;
}
else {
shortcutPressed = false;
}
},
keyup: function(event) {
if(shortcutPressed) {
event.preventDefault();
}
}
},

check: function() {
if( !module.should.allowCheck() ) {
return;
}
module.debug('Checking checkbox', $input);
module.set.checked();
if( !module.should.ignoreCallbacks() ) {
settings.onChecked.call(input);
module.trigger.change();
}
module.preventDefaultOnInputTarget();
},

uncheck: function() {
if( !module.should.allowUncheck() ) {
return;
}
module.debug('Unchecking checkbox');
module.set.unchecked();
if( !module.should.ignoreCallbacks() ) {
settings.onUnchecked.call(input);
module.trigger.change();
}
module.preventDefaultOnInputTarget();
},

indeterminate: function() {
if( module.should.allowIndeterminate() ) {
module.debug('Checkbox is already indeterminate');
return;
}
module.debug('Making checkbox indeterminate');
module.set.indeterminate();
if( !module.should.ignoreCallbacks() ) {
settings.onIndeterminate.call(input);
module.trigger.change();
}
},

determinate: function() {
if( module.should.allowDeterminate() ) {
module.debug('Checkbox is already determinate');
return;
}
module.debug('Making checkbox determinate');
module.set.determinate();
if( !module.should.ignoreCallbacks() ) {
settings.onDeterminate.call(input);
module.trigger.change();
}
},

enable: function() {
if( module.is.enabled() ) {
module.debug('Checkbox is already enabled');
return;
}
module.debug('Enabling checkbox');
module.set.enabled();
if( !module.should.ignoreCallbacks() ) {
settings.onEnable.call(input);
// preserve legacy callbacks
settings.onEnabled.call(input);
module.trigger.change();
}
},

disable: function() {
if( module.is.disabled() ) {
module.debug('Checkbox is already disabled');
return;
}
module.debug('Disabling checkbox');
module.set.disabled();
if( !module.should.ignoreCallbacks() ) {
settings.onDisable.call(input);
// preserve legacy callbacks
settings.onDisabled.call(input);
module.trigger.change();
}
},

get: {
radios: function() {
var
name = module.get.name()
;
return $('input[name="' + name + '"]').closest(selector.checkbox);
},
otherRadios: function() {
return module.get.radios().not($module);
},
name: function() {
return $input.attr('name');
}
},

is: {
initialLoad: function() {
return initialLoad;
},
radio: function() {
return ($input.hasClass(className.radio) || $input.attr('type') == 'radio');
},
indeterminate: function() {
return $input.prop('indeterminate') !== undefined && $input.prop('indeterminate');
},
checked: function() {
return $input.prop('checked') !== undefined && $input.prop('checked');
},
disabled: function() {
return $input.prop('disabled') !== undefined && $input.prop('disabled');
},
enabled: function() {
return !module.is.disabled();
},
determinate: function() {
return !module.is.indeterminate();
},
unchecked: function() {
return !module.is.checked();
}
},

should: {
allowCheck: function() {
if(module.is.determinate() && module.is.checked() && !module.is.initialLoad() ) {
module.debug('Should not allow check, checkbox is already checked');
return false;
}
if(!module.should.ignoreCallbacks() && settings.beforeChecked.apply(input) === false) {
module.debug('Should not allow check, beforeChecked cancelled');
return false;
}
return true;
},
allowUncheck: function() {
if(module.is.determinate() && module.is.unchecked() && !module.is.initialLoad() ) {
module.debug('Should not allow uncheck, checkbox is already unchecked');
return false;
}
if(!module.should.ignoreCallbacks() && settings.beforeUnchecked.apply(input) === false) {
module.debug('Should not allow uncheck, beforeUnchecked cancelled');
return false;
}
return true;
},
allowIndeterminate: function() {
if(module.is.indeterminate() && !module.is.initialLoad() ) {
module.debug('Should not allow indeterminate, checkbox is already indeterminate');
return false;
}
if(!module.should.ignoreCallbacks() && settings.beforeIndeterminate.apply(input) === false) {
module.debug('Should not allow indeterminate, beforeIndeterminate cancelled');
return false;
}
return true;
},
allowDeterminate: function() {
if(module.is.determinate() && !module.is.initialLoad() ) {
module.debug('Should not allow determinate, checkbox is already determinate');
return false;
}
if(!module.should.ignoreCallbacks() && settings.beforeDeterminate.apply(input) === false) {
module.debug('Should not allow determinate, beforeDeterminate cancelled');
return false;
}
return true;
},
ignoreCallbacks: function() {
return (initialLoad && !settings.fireOnInit);
}
},

can: {
change: function() {
return !( $module.hasClass(className.disabled) || $module.hasClass(className.readOnly) || $input.prop('disabled') || $input.prop('readonly') );
},
uncheck: function() {
return (typeof settings.uncheckable === 'boolean')
? settings.uncheckable
: !module.is.radio()
;
}
},

set: {
initialLoad: function() {
initialLoad = true;
},
checked: function() {
module.verbose('Setting class to checked');
$module
.removeClass(className.indeterminate)
.addClass(className.checked)
;
if( module.is.radio() ) {
module.uncheckOthers();
}
if(!module.is.indeterminate() && module.is.checked()) {
module.debug('Input is already checked, skipping input property change');
return;
}
module.verbose('Setting state to checked', input);
$input
.prop('indeterminate', false)
.prop('checked', true)
;
},
unchecked: function() {
module.verbose('Removing checked class');
$module
.removeClass(className.indeterminate)
.removeClass(className.checked)
;
if(!module.is.indeterminate() && module.is.unchecked() ) {
module.debug('Input is already unchecked');
return;
}
module.debug('Setting state to unchecked');
$input
.prop('indeterminate', false)
.prop('checked', false)
;
},
indeterminate: function() {
module.verbose('Setting class to indeterminate');
$module
.addClass(className.indeterminate)
;
if( module.is.indeterminate() ) {
module.debug('Input is already indeterminate, skipping input property change');
return;
}
module.debug('Setting state to indeterminate');
$input
.prop('indeterminate', true)
;
},
determinate: function() {
module.verbose('Removing indeterminate class');
$module
.removeClass(className.indeterminate)
;
if( module.is.determinate() ) {
module.debug('Input is already determinate, skipping input property change');
return;
}
module.debug('Setting state to determinate');
$input
.prop('indeterminate', false)
;
},
disabled: function() {
module.verbose('Setting class to disabled');
$module
.addClass(className.disabled)
;
if( module.is.disabled() ) {
module.debug('Input is already disabled, skipping input property change');
return;
}
module.debug('Setting state to disabled');
$input
.prop('disabled', 'disabled')
;
},
enabled: function() {
module.verbose('Removing disabled class');
$module.removeClass(className.disabled);
if( module.is.enabled() ) {
module.debug('Input is already enabled, skipping input property change');
return;
}
module.debug('Setting state to enabled');
$input
.prop('disabled', false)
;
},
tabbable: function() {
module.verbose('Adding tabindex to checkbox');
if( $input.attr('tabindex') === undefined) {
$input.attr('tabindex', 0);
}
}
},

remove: {
initialLoad: function() {
initialLoad = false;
}
},

trigger: {
change: function() {
var
inputElement = $input[0]
;
if(inputElement) {
var events = document.createEvent('HTMLEvents');
module.verbose('Triggering native change event');
events.initEvent('change', true, false);
inputElement.dispatchEvent(events);
}
}
},


create: {
label: function() {
if($input.prevAll(selector.label).length > 0) {
$input.prev(selector.label).detach().insertAfter($input);
module.debug('Moving existing label', $label);
}
else if( !module.has.label() ) {
$label = $('<label>').insertAfter($input);
module.debug('Creating label', $label);
}
}
},

has: {
label: function() {
return ($label.length > 0);
}
},

bind: {
events: function() {
module.verbose('Attaching checkbox events');
$module
.on('click' + eventNamespace, module.event.click)
.on('change' + eventNamespace, module.event.change)
.on('keydown' + eventNamespace, selector.input, module.event.keydown)
.on('keyup' + eventNamespace, selector.input, module.event.keyup)
;
}
},

unbind: {
events: function() {
module.debug('Removing events');
$module
.off(eventNamespace)
;
}
},

uncheckOthers: function() {
var
$radios = module.get.otherRadios()
;
module.debug('Unchecking other radios', $radios);
$radios.removeClass(className.checked);
},

toggle: function() {
if( !module.can.change() ) {
if(!module.is.radio()) {
module.debug('Checkbox is read-only or disabled, ignoring toggle');
}
return;
}
if( module.is.indeterminate() || module.is.unchecked() ) {
module.debug('Currently unchecked');
module.check();
}
else if( module.is.checked() && module.can.uncheck() ) {
module.debug('Currently checked');
module.uncheck();
}
},
setting: function(name, value) {
module.debug('Changing setting', name, value);
if( $.isPlainObject(name) ) {
$.extend(true, settings, name);
}
else if(value !== undefined) {
if($.isPlainObject(settings[name])) {
$.extend(true, settings[name], value);
}
else {
settings[name] = value;
}
}
else {
return settings[name];
}
},
internal: function(name, value) {
if( $.isPlainObject(name) ) {
$.extend(true, module, name);
}
else if(value !== undefined) {
module[name] = value;
}
else {
return module[name];
}
},
debug: function() {
if(!settings.silent && settings.debug) {
if(settings.performance) {
module.performance.log(arguments);
}
else {
module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
module.debug.apply(console, arguments);
}
}
},
verbose: function() {
if(!settings.silent && settings.verbose && settings.debug) {
if(settings.performance) {
module.performance.log(arguments);
}
else {
module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
module.verbose.apply(console, arguments);
}
}
},
error: function() {
if(!settings.silent) {
module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
module.error.apply(console, arguments);
}
},
performance: {
log: function(message) {
var
currentTime,
executionTime,
previousTime
;
if(settings.performance) {
currentTime = new Date().getTime();
previousTime = time || currentTime;
executionTime = currentTime - previousTime;
time = currentTime;
performance.push({
'Name' : message[0],
'Arguments' : [].slice.call(message, 1) || '',
'Element' : element,
'Execution Time' : executionTime
});
}
clearTimeout(module.performance.timer);
module.performance.timer = setTimeout(module.performance.display, 500);
},
display: function() {
var
title = settings.name + ':',
totalTime = 0
;
time = false;
clearTimeout(module.performance.timer);
$.each(performance, function(index, data) {
totalTime += data['Execution Time'];
});
title += ' ' + totalTime + 'ms';
if(moduleSelector) {
title += ' \'' + moduleSelector + '\'';
}
if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
console.groupCollapsed(title);
if(console.table) {
console.table(performance);
}
else {
$.each(performance, function(index, data) {
console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
});
}
console.groupEnd();
}
performance = [];
}
},
invoke: function(query, passedArguments, context) {
var
object = instance,
maxDepth,
found,
response
;
passedArguments = passedArguments || queryArguments;
context = element || context;
if(typeof query == 'string' && object !== undefined) {
query = query.split(/[\. ]/);
maxDepth = query.length - 1;
$.each(query, function(depth, value) {
var camelCaseValue = (depth != maxDepth)
? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
: query
;
if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
object = object[camelCaseValue];
}
else if( object[camelCaseValue] !== undefined ) {
found = object[camelCaseValue];
return false;
}
else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
object = object[value];
}
else if( object[value] !== undefined ) {
found = object[value];
return false;
}
else {
module.error(error.method, query);
return false;
}
});
}
if ( $.isFunction( found ) ) {
response = found.apply(context, passedArguments);
}
else if(found !== undefined) {
response = found;
}
if(Array.isArray(returnedValue)) {
returnedValue.push(response);
}
else if(returnedValue !== undefined) {
returnedValue = [returnedValue, response];
}
else if(response !== undefined) {
returnedValue = response;
}
return found;
}
};

if(methodInvoked) {
if(instance === undefined) {
module.initialize();
}
module.invoke(query);
}
else {
if(instance !== undefined) {
instance.invoke('destroy');
}
module.initialize();
}
})
;

return (returnedValue !== undefined)
? returnedValue
: this
;
};

$.fn.checkbox.settings = {

name : 'Checkbox',
namespace : 'checkbox',

silent : false,
debug : false,
verbose : true,
performance : true,

// delegated event context
uncheckable : 'auto',
fireOnInit : false,
enableEnterKey : true,

onChange : function(){},

beforeChecked : function(){},
beforeUnchecked : function(){},
beforeDeterminate : function(){},
beforeIndeterminate : function(){},

onChecked : function(){},
onUnchecked : function(){},

onDeterminate : function() {},
onIndeterminate : function() {},

onEnable : function(){},
onDisable : function(){},

// preserve misspelled callbacks (will be removed in 3.0)
onEnabled : function(){},
onDisabled : function(){},

className : {
checked : 'checked',
indeterminate : 'indeterminate',
disabled : 'disabled',
hidden : 'hidden',
radio : 'radio',
readOnly : 'read-only'
},

error : {
method : 'The method you called is not defined'
},

selector : {
checkbox : '.ui.checkbox',
label : 'label, .box',
input : 'input[type="checkbox"], input[type="radio"]',
link : 'a[href]'
}

};

})( jQuery, window, document );

/*!

+ 0
- 1
web_src/fomantic/semantic.json View File

@@ -23,7 +23,6 @@
"components": [
"api",
"button",
"checkbox",
"dimmer",
"dropdown",
"form",

+ 15
- 8
web_src/js/features/admin/common.js View File

@@ -218,17 +218,24 @@ export function initAdminCommon() {
});

// Select actions
const $checkboxes = $('.select.table .ui.checkbox');
const checkboxes = document.querySelectorAll('.select.table .ui.checkbox input');

$('.select.action').on('click', function () {
switch ($(this).data('action')) {
case 'select-all':
$checkboxes.checkbox('check');
for (const checkbox of checkboxes) {
checkbox.checked = true;
}
break;
case 'deselect-all':
$checkboxes.checkbox('uncheck');
for (const checkbox of checkboxes) {
checkbox.checked = false;
}
break;
case 'inverse':
$checkboxes.checkbox('toggle');
for (const checkbox of checkboxes) {
checkbox.checked = !checkbox.checked;
}
break;
}
});
@@ -236,11 +243,11 @@ export function initAdminCommon() {
e.preventDefault();
this.classList.add('is-loading', 'disabled');
const data = new FormData();
$checkboxes.each(function () {
if ($(this).checkbox('is checked')) {
data.append('ids[]', this.getAttribute('data-id'));
for (const checkbox of checkboxes) {
if (checkbox.checked) {
data.append('ids[]', checkbox.closest('.ui.checkbox').getAttribute('data-id'));
}
});
}
await POST(this.getAttribute('data-link'), {data});
window.location.href = this.getAttribute('data-redirect');
});

+ 0
- 2
web_src/js/features/common-global.js View File

@@ -195,8 +195,6 @@ export function initGlobalCommon() {
$uiDropdowns.filter('.upward').dropdown('setting', 'direction', 'upward');
$uiDropdowns.filter('.downward').dropdown('setting', 'direction', 'downward');

$('.ui.checkbox').checkbox();

$('.tabular.menu .item').tab();

initSubmitEventPolyfill();

+ 19
- 25
web_src/js/features/repo-issue.js View File

@@ -282,32 +282,26 @@ export function initRepoPullRequestMergeInstruction() {
}

export function initRepoPullRequestAllowMaintainerEdit() {
const checkbox = document.getElementById('allow-edits-from-maintainers');
if (!checkbox) return;

const $checkbox = $(checkbox);

const promptError = checkbox.getAttribute('data-prompt-error');
$checkbox.checkbox({
'onChange': async () => {
const checked = $checkbox.checkbox('is checked');
let url = checkbox.getAttribute('data-url');
url += '/set_allow_maintainer_edit';
$checkbox.checkbox('set disabled');
try {
const response = await POST(url, {
data: {allow_maintainer_edit: checked},
});
if (!response.ok) {
throw new Error('Failed to update maintainer edit permission');
}
} catch (error) {
console.error(error);
showTemporaryTooltip(checkbox, promptError);
} finally {
$checkbox.checkbox('set enabled');
const wrapper = document.getElementById('allow-edits-from-maintainers');
if (!wrapper) return;

wrapper.querySelector('input[type="checkbox"]')?.addEventListener('change', async (e) => {
const checked = e.target.checked;
const url = `${wrapper.getAttribute('data-url')}/set_allow_maintainer_edit`;
wrapper.classList.add('is-loading');
e.target.disabled = true;
try {
const response = await POST(url, {data: {allow_maintainer_edit: checked}});
if (!response.ok) {
throw new Error('Failed to update maintainer edit permission');
}
},
} catch (error) {
console.error(error);
showTemporaryTooltip(wrapper, wrapper.getAttribute('data-prompt-error'));
} finally {
wrapper.classList.remove('is-loading');
e.target.disabled = false;
}
});
}


+ 0
- 2
web_src/js/modules/fomantic.js View File

@@ -11,8 +11,6 @@ export const fomanticMobileScreen = window.matchMedia('only screen and (max-widt
export function initGiteaFomantic() {
// Silence fomantic's error logging when tabs are used without a target content element
$.fn.tab.settings.silent = true;
// Disable the behavior of fomantic to toggle the checkbox when you press enter on a checkbox element.
$.fn.checkbox.settings.enableEnterKey = false;

// By default, use "exact match" for full text search
$.fn.dropdown.settings.fullTextSearch = 'exact';

+ 6
- 11
web_src/js/modules/fomantic/aria.md View File

@@ -41,24 +41,19 @@ The ideal checkboxes should be:
<label><input type="checkbox"> ... </label>
```

However, related CSS styles aren't supported (not implemented) yet, so at the moment,
almost all the checkboxes are still using Fomantic UI checkbox.

## Fomantic UI Checkbox
However, the templates still have the Fomantic-style HTML layout:

```html
<div class="ui checkbox">
<input type="checkbox"> <!-- class "hidden" will be added by $.checkbox() -->
<input type="checkbox">
<label>...</label>
</div>
```

Then the JS `$.checkbox()` should be called to make it work with keyboard and label-clicking,
then it works like the ideal checkboxes.

There is still a problem: Fomantic UI checkbox is not friendly to screen readers,
so we add IDs to all the Fomantic UI checkboxes automatically by JS.
If the `label` part is empty, then the checkbox needs to get the `aria-label` attribute manually.
We call `initAriaCheckboxPatch` to link the `input` and `label` which makes clicking the
label etc. work. There is still a problem: These checkboxes are not friendly to screen readers,
so we add IDs to all the Fomantic UI checkboxes automatically by JS. If the `label` part is empty,
then the checkbox needs to get the `aria-label` attribute manually.

# Fomantic Dropdown


+ 10
- 33
web_src/js/modules/fomantic/checkbox.js View File

@@ -1,38 +1,15 @@
import $ from 'jquery';
import {generateAriaId} from './base.js';

const ariaPatchKey = '_giteaAriaPatchCheckbox';
const fomanticCheckboxFn = $.fn.checkbox;

// use our own `$.fn.checkbox` to patch Fomantic's checkbox module
export function initAriaCheckboxPatch() {
if ($.fn.checkbox === ariaCheckboxFn) throw new Error('initAriaCheckboxPatch could only be called once');
$.fn.checkbox = ariaCheckboxFn;
ariaCheckboxFn.settings = fomanticCheckboxFn.settings;
}

// the patched `$.fn.checkbox` checkbox function
// * it does the one-time attaching on the first call
function ariaCheckboxFn(...args) {
const ret = fomanticCheckboxFn.apply(this, args);
for (const el of this) {
if (el[ariaPatchKey]) continue;
attachInit(el);
// link the label and the input element so it's clickable and accessible
for (const el of document.querySelectorAll('.ui.checkbox')) {
if (el.hasAttribute('data-checkbox-patched')) continue;
const label = el.querySelector('label');
const input = el.querySelector('input');
if (!label || !input || input.getAttribute('id') || label.getAttribute('for')) continue;
const id = generateAriaId();
input.setAttribute('id', id);
label.setAttribute('for', id);
el.setAttribute('data-checkbox-patched', 'true');
}
return ret;
}

function attachInit(el) {
// Fomantic UI checkbox needs to be something like: <div class="ui checkbox"><label /><input /></div>
// It doesn't work well with <label><input />...</label>
// To make it work with aria, the "id"/"for" attributes are necessary, so add them automatically if missing.
// In the future, refactor to use native checkbox directly, then this patch could be removed.
el[ariaPatchKey] = {}; // record that this element has been patched
const label = el.querySelector('label');
const input = el.querySelector('input');
if (!label || !input || input.getAttribute('id')) return;

const id = generateAriaId();
input.setAttribute('id', id);
label.setAttribute('for', id);
}

Loading…
Cancel
Save