##// END OF EJS Templates
Se logró solucionar el problema del ID replicado al momento de crear un campaña con template experiment
Renato-TUF -
r367:9e304f85f976
parent child
Show More

The requested changes are too big and content was truncated. Show full diff

@@ -0,0 +1,14
1 # Generated by Django 4.1.5 on 2023-01-31 16:15
2
3 from django.db import migrations
4
5
6 class Migration(migrations.Migration):
7
8 dependencies = [
9 ('abs', '0002_auto_20230117_0948'),
10 ('abs', '0002_initial'),
11 ]
12
13 operations = [
14 ]
@@ -0,0 +1,3
1 CREATE USER docker WITH PASSWORD docker;
2 CREATE DATABASE radarsys;
3 GRANT ALL PRIVILEGES ON DATABASE radarsys TO docker; No newline at end of file
@@ -0,0 +1,33
1 @media (prefers-color-scheme: dark) {
2 :root {
3 --primary: #264b5d;
4 --primary-fg: #f7f7f7;
5
6 --body-fg: #eeeeee;
7 --body-bg: #121212;
8 --body-quiet-color: #e0e0e0;
9 --body-loud-color: #ffffff;
10
11 --breadcrumbs-link-fg: #e0e0e0;
12 --breadcrumbs-bg: var(--primary);
13
14 --link-fg: #81d4fa;
15 --link-hover-color: #4ac1f7;
16 --link-selected-fg: #6f94c6;
17
18 --hairline-color: #272727;
19 --border-color: #353535;
20
21 --error-fg: #e35f5f;
22 --message-success-bg: #006b1b;
23 --message-warning-bg: #583305;
24 --message-error-bg: #570808;
25
26 --darkened-bg: #212121;
27 --selected-bg: #1b1b1b;
28 --selected-row: #00363a;
29
30 --close-button-bg: #333333;
31 --close-button-hover-bg: #666666;
32 }
33 }
@@ -0,0 +1,139
1 .sticky {
2 position: sticky;
3 top: 0;
4 max-height: 100vh;
5 }
6
7 .toggle-nav-sidebar {
8 z-index: 20;
9 left: 0;
10 display: flex;
11 align-items: center;
12 justify-content: center;
13 flex: 0 0 23px;
14 width: 23px;
15 border: 0;
16 border-right: 1px solid var(--hairline-color);
17 background-color: var(--body-bg);
18 cursor: pointer;
19 font-size: 1.25rem;
20 color: var(--link-fg);
21 padding: 0;
22 }
23
24 [dir="rtl"] .toggle-nav-sidebar {
25 border-left: 1px solid var(--hairline-color);
26 border-right: 0;
27 }
28
29 .toggle-nav-sidebar:hover,
30 .toggle-nav-sidebar:focus {
31 background-color: var(--darkened-bg);
32 }
33
34 #nav-sidebar {
35 z-index: 15;
36 flex: 0 0 275px;
37 left: -276px;
38 margin-left: -276px;
39 border-top: 1px solid transparent;
40 border-right: 1px solid var(--hairline-color);
41 background-color: var(--body-bg);
42 overflow: auto;
43 }
44
45 [dir="rtl"] #nav-sidebar {
46 border-left: 1px solid var(--hairline-color);
47 border-right: 0;
48 left: 0;
49 margin-left: 0;
50 right: -276px;
51 margin-right: -276px;
52 }
53
54 .toggle-nav-sidebar::before {
55 content: '\00BB';
56 }
57
58 .main.shifted .toggle-nav-sidebar::before {
59 content: '\00AB';
60 }
61
62 .main.shifted > #nav-sidebar {
63 margin-left: 0;
64 }
65
66 [dir="rtl"] .main.shifted > #nav-sidebar {
67 margin-right: 0;
68 }
69
70 #nav-sidebar .module th {
71 width: 100%;
72 overflow-wrap: anywhere;
73 }
74
75 #nav-sidebar .module th,
76 #nav-sidebar .module caption {
77 padding-left: 16px;
78 }
79
80 #nav-sidebar .module td {
81 white-space: nowrap;
82 }
83
84 [dir="rtl"] #nav-sidebar .module th,
85 [dir="rtl"] #nav-sidebar .module caption {
86 padding-left: 8px;
87 padding-right: 16px;
88 }
89
90 #nav-sidebar .current-app .section:link,
91 #nav-sidebar .current-app .section:visited {
92 color: var(--header-color);
93 font-weight: bold;
94 }
95
96 #nav-sidebar .current-model {
97 background: var(--selected-row);
98 }
99
100 .main > #nav-sidebar + .content {
101 max-width: calc(100% - 23px);
102 }
103
104 .main.shifted > #nav-sidebar + .content {
105 max-width: calc(100% - 299px);
106 }
107
108 @media (max-width: 767px) {
109 #nav-sidebar, #toggle-nav-sidebar {
110 display: none;
111 }
112
113 .main > #nav-sidebar + .content,
114 .main.shifted > #nav-sidebar + .content {
115 max-width: 100%;
116 }
117 }
118
119 #nav-filter {
120 width: 100%;
121 box-sizing: border-box;
122 padding: 2px 5px;
123 margin: 5px 0;
124 border: 1px solid var(--border-color);
125 background-color: var(--darkened-bg);
126 color: var(--body-fg);
127 }
128
129 #nav-filter:focus {
130 border-color: var(--body-quiet-color);
131 }
132
133 #nav-filter.no-results {
134 background: var(--message-error-bg);
135 }
136
137 #nav-sidebar table {
138 width: 100%;
139 }
@@ -0,0 +1,30
1 /**
2 * Persist changelist filters state (collapsed/expanded).
3 */
4 'use strict';
5 {
6 // Init filters.
7 let filters = JSON.parse(sessionStorage.getItem('django.admin.filtersState'));
8
9 if (!filters) {
10 filters = {};
11 }
12
13 Object.entries(filters).forEach(([key, value]) => {
14 const detailElement = document.querySelector(`[data-filter-title='${key}']`);
15
16 // Check if the filter is present, it could be from other view.
17 if (detailElement) {
18 value ? detailElement.setAttribute('open', '') : detailElement.removeAttribute('open');
19 }
20 });
21
22 // Save filter state when clicks.
23 const details = document.querySelectorAll('details');
24 details.forEach(detail => {
25 detail.addEventListener('toggle', event => {
26 filters[`${event.target.dataset.filterTitle}`] = detail.open;
27 sessionStorage.setItem('django.admin.filtersState', JSON.stringify(filters));
28 });
29 });
30 }
@@ -0,0 +1,102
1 'use strict';
2 {
3 const toggleNavSidebar = document.getElementById('toggle-nav-sidebar');
4 if (toggleNavSidebar !== null) {
5 const navLinks = document.querySelectorAll('#nav-sidebar a');
6 function disableNavLinkTabbing() {
7 for (const navLink of navLinks) {
8 navLink.tabIndex = -1;
9 }
10 }
11 function enableNavLinkTabbing() {
12 for (const navLink of navLinks) {
13 navLink.tabIndex = 0;
14 }
15 }
16 function disableNavFilterTabbing() {
17 document.getElementById('nav-filter').tabIndex = -1;
18 }
19 function enableNavFilterTabbing() {
20 document.getElementById('nav-filter').tabIndex = 0;
21 }
22
23 const main = document.getElementById('main');
24 let navSidebarIsOpen = localStorage.getItem('django.admin.navSidebarIsOpen');
25 if (navSidebarIsOpen === null) {
26 navSidebarIsOpen = 'true';
27 }
28 if (navSidebarIsOpen === 'false') {
29 disableNavLinkTabbing();
30 disableNavFilterTabbing();
31 }
32 main.classList.toggle('shifted', navSidebarIsOpen === 'true');
33
34 toggleNavSidebar.addEventListener('click', function() {
35 if (navSidebarIsOpen === 'true') {
36 navSidebarIsOpen = 'false';
37 disableNavLinkTabbing();
38 disableNavFilterTabbing();
39 } else {
40 navSidebarIsOpen = 'true';
41 enableNavLinkTabbing();
42 enableNavFilterTabbing();
43 }
44 localStorage.setItem('django.admin.navSidebarIsOpen', navSidebarIsOpen);
45 main.classList.toggle('shifted');
46 });
47 }
48
49 function initSidebarQuickFilter() {
50 const options = [];
51 const navSidebar = document.getElementById('nav-sidebar');
52 if (!navSidebar) {
53 return;
54 }
55 navSidebar.querySelectorAll('th[scope=row] a').forEach((container) => {
56 options.push({title: container.innerHTML, node: container});
57 });
58
59 function checkValue(event) {
60 let filterValue = event.target.value;
61 if (filterValue) {
62 filterValue = filterValue.toLowerCase();
63 }
64 if (event.key === 'Escape') {
65 filterValue = '';
66 event.target.value = ''; // clear input
67 }
68 let matches = false;
69 for (const o of options) {
70 let displayValue = '';
71 if (filterValue) {
72 if (o.title.toLowerCase().indexOf(filterValue) === -1) {
73 displayValue = 'none';
74 } else {
75 matches = true;
76 }
77 }
78 // show/hide parent <TR>
79 o.node.parentNode.parentNode.style.display = displayValue;
80 }
81 if (!filterValue || matches) {
82 event.target.classList.remove('no-results');
83 } else {
84 event.target.classList.add('no-results');
85 }
86 sessionStorage.setItem('django.admin.navSidebarFilterValue', filterValue);
87 }
88
89 const nav = document.getElementById('nav-filter');
90 nav.addEventListener('change', checkValue, false);
91 nav.addEventListener('input', checkValue, false);
92 nav.addEventListener('keyup', checkValue, false);
93
94 const storedValue = sessionStorage.getItem('django.admin.navSidebarFilterValue');
95 if (storedValue) {
96 nav.value = storedValue;
97 checkValue({target: nav, key: ''});
98 }
99 }
100 window.initSidebarQuickFilter = initSidebarQuickFilter;
101 initSidebarQuickFilter();
102 }
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
@@ -4,9 +4,14 REDIS_PORT=6300
4 POSTGRES_PORT_5432_TCP_ADDR=radarsys-postgres
4 POSTGRES_PORT_5432_TCP_ADDR=radarsys-postgres
5 # POSTGRES_PORT_5432_TCP_PORT=5400
5 # POSTGRES_PORT_5432_TCP_PORT=5400
6 POSTGRES_PORT_5432_TCP_PORT=5432
6 POSTGRES_PORT_5432_TCP_PORT=5432
7 DB_NAME=radarsys
7 #POSTGRES_HOST?? DONDE IRIA
8 DB_USER=docker
8 POSTGRES_USER=docker
9 DB_PASSWORD=docker
9 POSTGRES_PASSWORD=docker
10 POSTGRES_DB=radarsys
11
12 # DB_NAME=radarsys
13 # DB_USER=docker
14 # DB_PASSWORD=docker
10 PGDATA=/var/lib/postgresql/data
15 PGDATA=/var/lib/postgresql/data
11 LC_ALL=C.UTF-8
16 LC_ALL=C.UTF-8
12 TZ=America/Lima
17 TZ=America/Lima
@@ -131,7 +131,7 h3 {
131 }
131 }
132
132
133 #sidebar a {
133 #sidebar a {
134 color: gray;
134 color: white;
135 padding: 0.1rem;
135 padding: 0.1rem;
136 }
136 }
137
137
@@ -441,9 +441,10 def campaign_new(request):
441 if form.is_valid():
441 if form.is_valid():
442 campaign = form.save(commit=False)
442 campaign = form.save(commit=False)
443 campaign.author = request.user
443 campaign.author = request.user
444 campaign.save()
444 for exp in experiments:
445 for exp in experiments:
445 campaign.experiments.add(exp)
446 campaign.experiments.add(exp)
446 campaign.save()
447
447 return redirect('url_campaign', id_camp=campaign.id)
448 return redirect('url_campaign', id_camp=campaign.id)
448
449
449 kwargs['form'] = form
450 kwargs['form'] = form
@@ -1,28 +1,28
1 version: '2'
1 version: '2'
2 services:
2 services:
3 # Django app
3 # Django app
4 web:
4 # web:
5 container_name: 'radarsys'
5 # container_name: 'radarsys'
6 build: .
6 # build: .
7 restart: always
7 # restart: always
8 image: radarsys
8 # image: radarsys
9 command: gunicorn radarsys.wsgi:application -w 2 -b :8000
9 # command: gunicorn radarsys.wsgi:application -w 2 -b :8000
10 #command: python manage.py runserver 0.0.0.0:8030
10 # #command: python manage.py runserver 0.0.0.0:8030
11 ports:
11 # ports:
12 - 8000:8000
12 # - 8000:8000
13 #ports:
13 # #ports:
14 # - 8030:8030
14 # # - 8030:8030
15 env_file: .env
15 # env_file: .env
16
16
17 links:
17 # links:
18 # - redis
18 # # - redis
19 - postgres
19 # - postgres
20 volumes:
20 # volumes:
21 - './:/radarsys'
21 # - './:/radarsys'
22 - '${DOCKER_DATA}/static:/radarsys/static'
22 # - '${DOCKER_DATA}/static:/radarsys/static'
23 depends_on:
23 # depends_on:
24 # - redis
24 # # - redis
25 - postgres
25 # - postgres
26
26
27 # redis:
27 # redis:
28 # container_name: 'radarsys-redis'
28 # container_name: 'radarsys-redis'
@@ -47,23 +47,27 services:
47 volumes:
47 volumes:
48 - ./postgres/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d
48 - ./postgres/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d
49 - pgdata:/var/lib/postgresql/data
49 - pgdata:/var/lib/postgresql/data
50 # ports:
50 ports:
51 # - 5432:5432
51 - 5432:5432
52 environment:
53 - POSTGRES_PASSWORD=docker
54 - POSTGRES_USER=docker
55 - POSTGRES_DB=radarsys
52 env_file: .env
56 env_file: .env
53
57
54 #Web Server
58 # #Web Server
55 nginx:
59 # nginx:
56 container_name: 'radarsys-nginx'
60 # container_name: 'radarsys-nginx'
57 restart: always
61 # restart: always
58 build: ./nginx/
62 # build: ./nginx/
59 ports:
63 # ports:
60 - '8030:8030'
64 # - '8030:8030'
61 volumes_from:
65 # volumes_from:
62 - web
66 # - web
63 links:
67 # links:
64 - web:web
68 # - web:web
65 depends_on:
69 # depends_on:
66 - web
70 # - web
67
71
68 volumes:
72 volumes:
69 pgdata:
73 pgdata:
@@ -1,3 +1,5
1 FROM postgres:14.6-alpine
1 FROM postgres:14.6-alpine
2 #FROM library/postgres
2
3
3 RUN mkdir -p "$PGDATA" && chmod 700 "$PGDATA" No newline at end of file
4 RUN mkdir -p "$PGDATA" && chmod 700 "$PGDATA"
5 #COPY ./init.sql /docker-entrypoint-initdb.d/ No newline at end of file
@@ -2,8 +2,8
2 set -e
2 set -e
3
3
4 echo "Creating database & user"
4 echo "Creating database & user"
5 psql -v --username "postgres" --dbname "postgres" <<-EOSQL
5 psql -v --username "docker" --dbname "radarsys" <<-EOSQL
6 CREATE USER $DB_USER WITH PASSWORD '$DB_PASSWORD';
6 CREATE USER docker WITH PASSWORD 'docker';
7 CREATE DATABASE $DB_NAME;
7 CREATE DATABASE radarsys;
8 GRANT ALL PRIVILEGES ON DATABASE $DB_NAME TO $DB_USER;
8 GRANT ALL PRIVILEGES ON DATABASE radarsys TO docker;
9 EOSQL
9 EOSQL
@@ -14,7 +14,7 select.admin-autocomplete {
14
14
15 .select2-container--admin-autocomplete.select2-container--focus .select2-selection,
15 .select2-container--admin-autocomplete.select2-container--focus .select2-selection,
16 .select2-container--admin-autocomplete.select2-container--open .select2-selection {
16 .select2-container--admin-autocomplete.select2-container--open .select2-selection {
17 border-color: #999;
17 border-color: var(--body-quiet-color);
18 min-height: 30px;
18 min-height: 30px;
19 }
19 }
20
20
@@ -29,13 +29,13 select.admin-autocomplete {
29 }
29 }
30
30
31 .select2-container--admin-autocomplete .select2-selection--single {
31 .select2-container--admin-autocomplete .select2-selection--single {
32 background-color: #fff;
32 background-color: var(--body-bg);
33 border: 1px solid #ccc;
33 border: 1px solid var(--border-color);
34 border-radius: 4px;
34 border-radius: 4px;
35 }
35 }
36
36
37 .select2-container--admin-autocomplete .select2-selection--single .select2-selection__rendered {
37 .select2-container--admin-autocomplete .select2-selection--single .select2-selection__rendered {
38 color: #444;
38 color: var(--body-fg);
39 line-height: 30px;
39 line-height: 30px;
40 }
40 }
41
41
@@ -46,7 +46,7 select.admin-autocomplete {
46 }
46 }
47
47
48 .select2-container--admin-autocomplete .select2-selection--single .select2-selection__placeholder {
48 .select2-container--admin-autocomplete .select2-selection--single .select2-selection__placeholder {
49 color: #999;
49 color: var(--body-quiet-color);
50 }
50 }
51
51
52 .select2-container--admin-autocomplete .select2-selection--single .select2-selection__arrow {
52 .select2-container--admin-autocomplete .select2-selection--single .select2-selection__arrow {
@@ -80,7 +80,7 select.admin-autocomplete {
80 }
80 }
81
81
82 .select2-container--admin-autocomplete.select2-container--disabled .select2-selection--single {
82 .select2-container--admin-autocomplete.select2-container--disabled .select2-selection--single {
83 background-color: #eee;
83 background-color: var(--darkened-bg);
84 cursor: default;
84 cursor: default;
85 }
85 }
86
86
@@ -94,8 +94,8 select.admin-autocomplete {
94 }
94 }
95
95
96 .select2-container--admin-autocomplete .select2-selection--multiple {
96 .select2-container--admin-autocomplete .select2-selection--multiple {
97 background-color: white;
97 background-color: var(--body-bg);
98 border: 1px solid #ccc;
98 border: 1px solid var(--border-color);
99 border-radius: 4px;
99 border-radius: 4px;
100 cursor: text;
100 cursor: text;
101 }
101 }
@@ -104,8 +104,10 select.admin-autocomplete {
104 box-sizing: border-box;
104 box-sizing: border-box;
105 list-style: none;
105 list-style: none;
106 margin: 0;
106 margin: 0;
107 padding: 0 5px;
107 padding: 0 10px 5px 5px;
108 width: 100%;
108 width: 100%;
109 display: flex;
110 flex-wrap: wrap;
109 }
111 }
110
112
111 .select2-container--admin-autocomplete .select2-selection--multiple .select2-selection__rendered li {
113 .select2-container--admin-autocomplete .select2-selection--multiple .select2-selection__rendered li {
@@ -113,7 +115,7 select.admin-autocomplete {
113 }
115 }
114
116
115 .select2-container--admin-autocomplete .select2-selection--multiple .select2-selection__placeholder {
117 .select2-container--admin-autocomplete .select2-selection--multiple .select2-selection__placeholder {
116 color: #999;
118 color: var(--body-quiet-color);
117 margin-top: 5px;
119 margin-top: 5px;
118 float: left;
120 float: left;
119 }
121 }
@@ -123,11 +125,13 select.admin-autocomplete {
123 float: right;
125 float: right;
124 font-weight: bold;
126 font-weight: bold;
125 margin: 5px;
127 margin: 5px;
128 position: absolute;
129 right: 0;
126 }
130 }
127
131
128 .select2-container--admin-autocomplete .select2-selection--multiple .select2-selection__choice {
132 .select2-container--admin-autocomplete .select2-selection--multiple .select2-selection__choice {
129 background-color: #e4e4e4;
133 background-color: var(--darkened-bg);
130 border: 1px solid #ccc;
134 border: 1px solid var(--border-color);
131 border-radius: 4px;
135 border-radius: 4px;
132 cursor: default;
136 cursor: default;
133 float: left;
137 float: left;
@@ -137,7 +141,7 select.admin-autocomplete {
137 }
141 }
138
142
139 .select2-container--admin-autocomplete .select2-selection--multiple .select2-selection__choice__remove {
143 .select2-container--admin-autocomplete .select2-selection--multiple .select2-selection__choice__remove {
140 color: #999;
144 color: var(--body-quiet-color);
141 cursor: pointer;
145 cursor: pointer;
142 display: inline-block;
146 display: inline-block;
143 font-weight: bold;
147 font-weight: bold;
@@ -145,7 +149,7 select.admin-autocomplete {
145 }
149 }
146
150
147 .select2-container--admin-autocomplete .select2-selection--multiple .select2-selection__choice__remove:hover {
151 .select2-container--admin-autocomplete .select2-selection--multiple .select2-selection__choice__remove:hover {
148 color: #333;
152 color: var(--body-fg);
149 }
153 }
150
154
151 .select2-container--admin-autocomplete[dir="rtl"] .select2-selection--multiple .select2-selection__choice, .select2-container--admin-autocomplete[dir="rtl"] .select2-selection--multiple .select2-selection__placeholder, .select2-container--admin-autocomplete[dir="rtl"] .select2-selection--multiple .select2-search--inline {
155 .select2-container--admin-autocomplete[dir="rtl"] .select2-selection--multiple .select2-selection__choice, .select2-container--admin-autocomplete[dir="rtl"] .select2-selection--multiple .select2-selection__placeholder, .select2-container--admin-autocomplete[dir="rtl"] .select2-selection--multiple .select2-search--inline {
@@ -163,12 +167,12 select.admin-autocomplete {
163 }
167 }
164
168
165 .select2-container--admin-autocomplete.select2-container--focus .select2-selection--multiple {
169 .select2-container--admin-autocomplete.select2-container--focus .select2-selection--multiple {
166 border: solid #999 1px;
170 border: solid var(--body-quiet-color) 1px;
167 outline: 0;
171 outline: 0;
168 }
172 }
169
173
170 .select2-container--admin-autocomplete.select2-container--disabled .select2-selection--multiple {
174 .select2-container--admin-autocomplete.select2-container--disabled .select2-selection--multiple {
171 background-color: #eee;
175 background-color: var(--darkened-bg);
172 cursor: default;
176 cursor: default;
173 }
177 }
174
178
@@ -186,12 +190,20 select.admin-autocomplete {
186 border-bottom-right-radius: 0;
190 border-bottom-right-radius: 0;
187 }
191 }
188
192
193 .select2-container--admin-autocomplete .select2-search--dropdown {
194 background: var(--darkened-bg);
195 }
196
189 .select2-container--admin-autocomplete .select2-search--dropdown .select2-search__field {
197 .select2-container--admin-autocomplete .select2-search--dropdown .select2-search__field {
190 border: 1px solid #ccc;
198 background: var(--body-bg);
199 color: var(--body-fg);
200 border: 1px solid var(--border-color);
201 border-radius: 4px;
191 }
202 }
192
203
193 .select2-container--admin-autocomplete .select2-search--inline .select2-search__field {
204 .select2-container--admin-autocomplete .select2-search--inline .select2-search__field {
194 background: transparent;
205 background: transparent;
206 color: var(--body-fg);
195 border: none;
207 border: none;
196 outline: 0;
208 outline: 0;
197 box-shadow: none;
209 box-shadow: none;
@@ -201,6 +213,8 select.admin-autocomplete {
201 .select2-container--admin-autocomplete .select2-results > .select2-results__options {
213 .select2-container--admin-autocomplete .select2-results > .select2-results__options {
202 max-height: 200px;
214 max-height: 200px;
203 overflow-y: auto;
215 overflow-y: auto;
216 color: var(--body-fg);
217 background: var(--body-bg);
204 }
218 }
205
219
206 .select2-container--admin-autocomplete .select2-results__option[role=group] {
220 .select2-container--admin-autocomplete .select2-results__option[role=group] {
@@ -208,11 +222,12 select.admin-autocomplete {
208 }
222 }
209
223
210 .select2-container--admin-autocomplete .select2-results__option[aria-disabled=true] {
224 .select2-container--admin-autocomplete .select2-results__option[aria-disabled=true] {
211 color: #999;
225 color: var(--body-quiet-color);
212 }
226 }
213
227
214 .select2-container--admin-autocomplete .select2-results__option[aria-selected=true] {
228 .select2-container--admin-autocomplete .select2-results__option[aria-selected=true] {
215 background-color: #ddd;
229 background-color: var(--selected-bg);
230 color: var(--body-fg);
216 }
231 }
217
232
218 .select2-container--admin-autocomplete .select2-results__option .select2-results__option {
233 .select2-container--admin-autocomplete .select2-results__option .select2-results__option {
@@ -249,8 +264,8 select.admin-autocomplete {
249 }
264 }
250
265
251 .select2-container--admin-autocomplete .select2-results__option--highlighted[aria-selected] {
266 .select2-container--admin-autocomplete .select2-results__option--highlighted[aria-selected] {
252 background-color: #79aec8;
267 background-color: var(--primary);
253 color: white;
268 color: var(--primary-fg);
254 }
269 }
255
270
256 .select2-container--admin-autocomplete .select2-results__group {
271 .select2-container--admin-autocomplete .select2-results__group {
@@ -4,24 +4,82
4
4
5 @import url(fonts.css);
5 @import url(fonts.css);
6
6
7 /* VARIABLE DEFINITIONS */
8 :root {
9 --primary: #79aec8;
10 --secondary: #417690;
11 --accent: #f5dd5d;
12 --primary-fg: #fff;
13
14 --body-fg: #333;
15 --body-bg: #fff;
16 --body-quiet-color: #666;
17 --body-loud-color: #000;
18
19 --header-color: #ffc;
20 --header-branding-color: var(--accent);
21 --header-bg: var(--secondary);
22 --header-link-color: var(--primary-fg);
23
24 --breadcrumbs-fg: #c4dce8;
25 --breadcrumbs-link-fg: var(--body-bg);
26 --breadcrumbs-bg: var(--primary);
27
28 --link-fg: #447e9b;
29 --link-hover-color: #036;
30 --link-selected-fg: #5b80b2;
31
32 --hairline-color: #e8e8e8;
33 --border-color: #ccc;
34
35 --error-fg: #ba2121;
36
37 --message-success-bg: #dfd;
38 --message-warning-bg: #ffc;
39 --message-error-bg: #ffefef;
40
41 --darkened-bg: #f8f8f8; /* A bit darker than --body-bg */
42 --selected-bg: #e4e4e4; /* E.g. selected table cells */
43 --selected-row: #ffc;
44
45 --button-fg: #fff;
46 --button-bg: var(--primary);
47 --button-hover-bg: #609ab6;
48 --default-button-bg: var(--secondary);
49 --default-button-hover-bg: #205067;
50 --close-button-bg: #888; /* Previously #bbb, contrast 1.92 */
51 --close-button-hover-bg: #747474;
52 --delete-button-bg: #ba2121;
53 --delete-button-hover-bg: #a41515;
54
55 --object-tools-fg: var(--button-fg);
56 --object-tools-bg: var(--close-button-bg);
57 --object-tools-hover-bg: var(--close-button-hover-bg);
58 }
59
60 html, body {
61 height: 100%;
62 }
63
7 body {
64 body {
8 margin: 0;
65 margin: 0;
9 padding: 0;
66 padding: 0;
10 font-size: 14px;
67 font-size: 0.875rem;
11 font-family: "Roboto","Lucida Grande","DejaVu Sans","Bitstream Vera Sans",Verdana,Arial,sans-serif;
68 font-family: "Roboto","Lucida Grande","DejaVu Sans","Bitstream Vera Sans",Verdana,Arial,sans-serif;
12 color: #333;
69 color: var(--body-fg);
13 background: #fff;
70 background: var(--body-bg);
14 }
71 }
15
72
16 /* LINKS */
73 /* LINKS */
17
74
18 a:link, a:visited {
75 a:link, a:visited {
19 color: #447e9b;
76 color: var(--link-fg);
20 text-decoration: none;
77 text-decoration: none;
78 transition: color 0.15s, background 0.15s;
21 }
79 }
22
80
23 a:focus, a:hover {
81 a:focus, a:hover {
24 color: #036;
82 color: var(--link-hover-color);
25 }
83 }
26
84
27 a:focus {
85 a:focus {
@@ -33,7 +91,7 a img {
33 }
91 }
34
92
35 a.section:link, a.section:visited {
93 a.section:link, a.section:visited {
36 color: #fff;
94 color: var(--header-link-color);
37 text-decoration: none;
95 text-decoration: none;
38 }
96 }
39
97
@@ -59,12 +117,12 h1,h2,h3,h4,h5 {
59 h1 {
117 h1 {
60 margin: 0 0 20px;
118 margin: 0 0 20px;
61 font-weight: 300;
119 font-weight: 300;
62 font-size: 20px;
120 font-size: 1.25rem;
63 color: #666;
121 color: var(--body-quiet-color);
64 }
122 }
65
123
66 h2 {
124 h2 {
67 font-size: 16px;
125 font-size: 1rem;
68 margin: 1em 0 .5em 0;
126 margin: 1em 0 .5em 0;
69 }
127 }
70
128
@@ -74,27 +132,27 h2.subhead {
74 }
132 }
75
133
76 h3 {
134 h3 {
77 font-size: 14px;
135 font-size: 0.875rem;
78 margin: .8em 0 .3em 0;
136 margin: .8em 0 .3em 0;
79 color: #666;
137 color: var(--body-quiet-color);
80 font-weight: bold;
138 font-weight: bold;
81 }
139 }
82
140
83 h4 {
141 h4 {
84 font-size: 12px;
142 font-size: 0.75rem;
85 margin: 1em 0 .8em 0;
143 margin: 1em 0 .8em 0;
86 padding-bottom: 3px;
144 padding-bottom: 3px;
87 }
145 }
88
146
89 h5 {
147 h5 {
90 font-size: 10px;
148 font-size: 0.625rem;
91 margin: 1.5em 0 .5em 0;
149 margin: 1.5em 0 .5em 0;
92 color: #666;
150 color: var(--body-quiet-color);
93 text-transform: uppercase;
151 text-transform: uppercase;
94 letter-spacing: 1px;
152 letter-spacing: 1px;
95 }
153 }
96
154
97 ul li {
155 ul > li {
98 list-style-type: square;
156 list-style-type: square;
99 padding: 1px 0;
157 padding: 1px 0;
100 }
158 }
@@ -104,7 +162,7 li ul {
104 }
162 }
105
163
106 li, dt, dd {
164 li, dt, dd {
107 font-size: 13px;
165 font-size: 0.8125rem;
108 line-height: 20px;
166 line-height: 20px;
109 }
167 }
110
168
@@ -124,13 +182,14 form {
124
182
125 fieldset {
183 fieldset {
126 margin: 0;
184 margin: 0;
185 min-width: 0;
127 padding: 0;
186 padding: 0;
128 border: none;
187 border: none;
129 border-top: 1px solid #eee;
188 border-top: 1px solid var(--hairline-color);
130 }
189 }
131
190
132 blockquote {
191 blockquote {
133 font-size: 11px;
192 font-size: 0.6875rem;
134 color: #777;
193 color: #777;
135 margin-left: 2px;
194 margin-left: 2px;
136 padding-left: 10px;
195 padding-left: 10px;
@@ -139,13 +198,14 blockquote {
139
198
140 code, pre {
199 code, pre {
141 font-family: "Bitstream Vera Sans Mono", Monaco, "Courier New", Courier, monospace;
200 font-family: "Bitstream Vera Sans Mono", Monaco, "Courier New", Courier, monospace;
142 color: #666;
201 color: var(--body-quiet-color);
143 font-size: 12px;
202 font-size: 0.75rem;
203 overflow-x: auto;
144 }
204 }
145
205
146 pre.literal-block {
206 pre.literal-block {
147 margin: 10px;
207 margin: 10px;
148 background: #eee;
208 background: var(--darkened-bg);
149 padding: 6px 8px;
209 padding: 6px 8px;
150 }
210 }
151
211
@@ -155,41 +215,28 code strong {
155
215
156 hr {
216 hr {
157 clear: both;
217 clear: both;
158 color: #eee;
218 color: var(--hairline-color);
159 background-color: #eee;
219 background-color: var(--hairline-color);
160 height: 1px;
220 height: 1px;
161 border: none;
221 border: none;
162 margin: 0;
222 margin: 0;
163 padding: 0;
223 padding: 0;
164 font-size: 1px;
165 line-height: 1px;
224 line-height: 1px;
166 }
225 }
167
226
168 /* TEXT STYLES & MODIFIERS */
227 /* TEXT STYLES & MODIFIERS */
169
228
170 .small {
229 .small {
171 font-size: 11px;
230 font-size: 0.6875rem;
172 }
173
174 .tiny {
175 font-size: 10px;
176 }
177
178 p.tiny {
179 margin-top: -2px;
180 }
231 }
181
232
182 .mini {
233 .mini {
183 font-size: 10px;
234 font-size: 0.625rem;
184 }
185
186 p.mini {
187 margin-top: -3px;
188 }
235 }
189
236
190 .help, p.help, form p.help, div.help, form div.help, div.help li {
237 .help, p.help, form p.help, div.help, form div.help, div.help li {
191 font-size: 11px;
238 font-size: 0.6875rem;
192 color: #999;
239 color: var(--body-quiet-color);
193 }
240 }
194
241
195 div.help ul {
242 div.help ul {
@@ -205,54 +252,35 p img, h1 img, h2 img, h3 img, h4 img, td img {
205 }
252 }
206
253
207 .quiet, a.quiet:link, a.quiet:visited {
254 .quiet, a.quiet:link, a.quiet:visited {
208 color: #999;
255 color: var(--body-quiet-color);
209 font-weight: normal;
256 font-weight: normal;
210 }
257 }
211
258
212 .float-right {
213 float: right;
214 }
215
216 .float-left {
217 float: left;
218 }
219
220 .clear {
259 .clear {
221 clear: both;
260 clear: both;
222 }
261 }
223
262
224 .align-left {
225 text-align: left;
226 }
227
228 .align-right {
229 text-align: right;
230 }
231
232 .example {
233 margin: 10px 0;
234 padding: 5px 10px;
235 background: #efefef;
236 }
237
238 .nowrap {
263 .nowrap {
239 white-space: nowrap;
264 white-space: nowrap;
240 }
265 }
241
266
267 .hidden {
268 display: none !important;
269 }
270
242 /* TABLES */
271 /* TABLES */
243
272
244 table {
273 table {
245 border-collapse: collapse;
274 border-collapse: collapse;
246 border-color: #ccc;
275 border-color: var(--border-color);
247 }
276 }
248
277
249 td, th {
278 td, th {
250 font-size: 13px;
279 font-size: 0.8125rem;
251 line-height: 16px;
280 line-height: 16px;
252 border-bottom: 1px solid #eee;
281 border-bottom: 1px solid var(--hairline-color);
253 vertical-align: top;
282 vertical-align: top;
254 padding: 8px;
283 padding: 8px;
255 font-family: "Roboto", "Lucida Grande", Verdana, Arial, sans-serif;
256 }
284 }
257
285
258 th {
286 th {
@@ -262,34 +290,37 th {
262
290
263 thead th,
291 thead th,
264 tfoot td {
292 tfoot td {
265 color: #666;
293 color: var(--body-quiet-color);
266 padding: 5px 10px;
294 padding: 5px 10px;
267 font-size: 11px;
295 font-size: 0.6875rem;
268 background: #fff;
296 background: var(--body-bg);
269 border: none;
297 border: none;
270 border-top: 1px solid #eee;
298 border-top: 1px solid var(--hairline-color);
271 border-bottom: 1px solid #eee;
299 border-bottom: 1px solid var(--hairline-color);
272 }
300 }
273
301
274 tfoot td {
302 tfoot td {
275 border-bottom: none;
303 border-bottom: none;
276 border-top: 1px solid #eee;
304 border-top: 1px solid var(--hairline-color);
277 }
305 }
278
306
279 thead th.required {
307 thead th.required {
280 color: #000;
308 color: var(--body-loud-color);
281 }
309 }
282
310
283 tr.alt {
311 tr.alt {
284 background: #f6f6f6;
312 background: var(--darkened-bg);
285 }
313 }
286
314
287 .row1 {
315 tr:nth-child(odd), .row-form-errors {
288 background: #fff;
316 background: var(--body-bg);
289 }
317 }
290
318
291 .row2 {
319 tr:nth-child(even),
292 background: #f9f9f9;
320 tr:nth-child(even) .errorlist,
321 tr:nth-child(odd) + .row-form-errors,
322 tr:nth-child(odd) + .row-form-errors .errorlist {
323 background: var(--darkened-bg);
293 }
324 }
294
325
295 /* SORTABLE TABLES */
326 /* SORTABLE TABLES */
@@ -298,15 +329,15 thead th {
298 padding: 5px 10px;
329 padding: 5px 10px;
299 line-height: normal;
330 line-height: normal;
300 text-transform: uppercase;
331 text-transform: uppercase;
301 background: #f6f6f6;
332 background: var(--darkened-bg);
302 }
333 }
303
334
304 thead th a:link, thead th a:visited {
335 thead th a:link, thead th a:visited {
305 color: #666;
336 color: var(--body-quiet-color);
306 }
337 }
307
338
308 thead th.sorted {
339 thead th.sorted {
309 background: #eee;
340 background: var(--selected-bg);
310 }
341 }
311
342
312 thead th.sorted .text {
343 thead th.sorted .text {
@@ -325,7 +356,7 table thead th .text a {
325 }
356 }
326
357
327 table thead th .text a:focus, table thead th .text a:hover {
358 table thead th .text a:focus, table thead th .text a:hover {
328 background: #eee;
359 background: var(--selected-bg);
329 }
360 }
330
361
331 thead th.sorted a.sortremove {
362 thead th.sorted a.sortremove {
@@ -371,13 +402,13 table thead th.sorted .sortoptions a.sortremove:after {
371 top: -6px;
402 top: -6px;
372 left: 3px;
403 left: 3px;
373 font-weight: 200;
404 font-weight: 200;
374 font-size: 18px;
405 font-size: 1.125rem;
375 color: #999;
406 color: var(--body-quiet-color);
376 }
407 }
377
408
378 table thead th.sorted .sortoptions a.sortremove:focus:after,
409 table thead th.sorted .sortoptions a.sortremove:focus:after,
379 table thead th.sorted .sortoptions a.sortremove:hover:after {
410 table thead th.sorted .sortoptions a.sortremove:hover:after {
380 color: #447e9b;
411 color: var(--link-fg);
381 }
412 }
382
413
383 table thead th.sorted .sortoptions a.sortremove:focus,
414 table thead th.sorted .sortoptions a.sortremove:focus,
@@ -412,7 +443,7 input, textarea, select, .form-row p, form .button {
412 vertical-align: middle;
443 vertical-align: middle;
413 font-family: "Roboto", "Lucida Grande", Verdana, Arial, sans-serif;
444 font-family: "Roboto", "Lucida Grande", Verdana, Arial, sans-serif;
414 font-weight: normal;
445 font-weight: normal;
415 font-size: 13px;
446 font-size: 0.8125rem;
416 }
447 }
417 .form-row div.help {
448 .form-row div.help {
418 padding: 2px 3px;
449 padding: 2px 3px;
@@ -424,16 +455,18 textarea {
424
455
425 input[type=text], input[type=password], input[type=email], input[type=url],
456 input[type=text], input[type=password], input[type=email], input[type=url],
426 input[type=number], input[type=tel], textarea, select, .vTextField {
457 input[type=number], input[type=tel], textarea, select, .vTextField {
427 border: 1px solid #ccc;
458 border: 1px solid var(--border-color);
428 border-radius: 4px;
459 border-radius: 4px;
429 padding: 5px 6px;
460 padding: 5px 6px;
430 margin-top: 0;
461 margin-top: 0;
462 color: var(--body-fg);
463 background-color: var(--body-bg);
431 }
464 }
432
465
433 input[type=text]:focus, input[type=password]:focus, input[type=email]:focus,
466 input[type=text]:focus, input[type=password]:focus, input[type=email]:focus,
434 input[type=url]:focus, input[type=number]:focus, input[type=tel]:focus,
467 input[type=url]:focus, input[type=number]:focus, input[type=tel]:focus,
435 textarea:focus, select:focus, .vTextField:focus {
468 textarea:focus, select:focus, .vTextField:focus {
436 border-color: #999;
469 border-color: var(--body-quiet-color);
437 }
470 }
438
471
439 select {
472 select {
@@ -449,12 +482,13 select[multiple] {
449 /* FORM BUTTONS */
482 /* FORM BUTTONS */
450
483
451 .button, input[type=submit], input[type=button], .submit-row input, a.button {
484 .button, input[type=submit], input[type=button], .submit-row input, a.button {
452 background: #79aec8;
485 background: var(--button-bg);
453 padding: 10px 15px;
486 padding: 10px 15px;
454 border: none;
487 border: none;
455 border-radius: 4px;
488 border-radius: 4px;
456 color: #fff;
489 color: var(--button-fg);
457 cursor: pointer;
490 cursor: pointer;
491 transition: background 0.15s;
458 }
492 }
459
493
460 a.button {
494 a.button {
@@ -464,7 +498,7 a.button {
464 .button:active, input[type=submit]:active, input[type=button]:active,
498 .button:active, input[type=submit]:active, input[type=button]:active,
465 .button:focus, input[type=submit]:focus, input[type=button]:focus,
499 .button:focus, input[type=submit]:focus, input[type=button]:focus,
466 .button:hover, input[type=submit]:hover, input[type=button]:hover {
500 .button:hover, input[type=submit]:hover, input[type=button]:hover {
467 background: #609ab6;
501 background: var(--button-hover-bg);
468 }
502 }
469
503
470 .button[disabled], input[type=submit][disabled], input[type=button][disabled] {
504 .button[disabled], input[type=submit][disabled], input[type=button][disabled] {
@@ -475,13 +509,13 a.button {
475 float: right;
509 float: right;
476 border: none;
510 border: none;
477 font-weight: 400;
511 font-weight: 400;
478 background: #417690;
512 background: var(--default-button-bg);
479 }
513 }
480
514
481 .button.default:active, input[type=submit].default:active,
515 .button.default:active, input[type=submit].default:active,
482 .button.default:focus, input[type=submit].default:focus,
516 .button.default:focus, input[type=submit].default:focus,
483 .button.default:hover, input[type=submit].default:hover {
517 .button.default:hover, input[type=submit].default:hover {
484 background: #205067;
518 background: var(--default-button-hover-bg);
485 }
519 }
486
520
487 .button[disabled].default,
521 .button[disabled].default,
@@ -496,7 +530,7 input[type=button][disabled].default {
496 .module {
530 .module {
497 border: none;
531 border: none;
498 margin-bottom: 30px;
532 margin-bottom: 30px;
499 background: #fff;
533 background: var(--body-bg);
500 }
534 }
501
535
502 .module p, .module ul, .module h3, .module h4, .module dl, .module pre {
536 .module p, .module ul, .module h3, .module h4, .module dl, .module pre {
@@ -520,15 +554,15 input[type=button][disabled].default {
520 margin: 0;
554 margin: 0;
521 padding: 8px;
555 padding: 8px;
522 font-weight: 400;
556 font-weight: 400;
523 font-size: 13px;
557 font-size: 0.8125rem;
524 text-align: left;
558 text-align: left;
525 background: #79aec8;
559 background: var(--primary);
526 color: #fff;
560 color: var(--header-link-color);
527 }
561 }
528
562
529 .module caption,
563 .module caption,
530 .inline-group h2 {
564 .inline-group h2 {
531 font-size: 12px;
565 font-size: 0.75rem;
532 letter-spacing: 0.5px;
566 letter-spacing: 0.5px;
533 text-transform: uppercase;
567 text-transform: uppercase;
534 }
568 }
@@ -547,48 +581,51 ul.messagelist {
547 ul.messagelist li {
581 ul.messagelist li {
548 display: block;
582 display: block;
549 font-weight: 400;
583 font-weight: 400;
550 font-size: 13px;
584 font-size: 0.8125rem;
551 padding: 10px 10px 10px 65px;
585 padding: 10px 10px 10px 65px;
552 margin: 0 0 10px 0;
586 margin: 0 0 10px 0;
553 background: #dfd url(../img/icon-yes.svg) 40px 12px no-repeat;
587 background: var(--message-success-bg) url(../img/icon-yes.svg) 40px 12px no-repeat;
554 background-size: 16px auto;
588 background-size: 16px auto;
555 color: #333;
589 color: var(--body-fg);
590 word-break: break-word;
556 }
591 }
557
592
558 ul.messagelist li.warning {
593 ul.messagelist li.warning {
559 background: #ffc url(../img/icon-alert.svg) 40px 14px no-repeat;
594 background: var(--message-warning-bg) url(../img/icon-alert.svg) 40px 14px no-repeat;
560 background-size: 14px auto;
595 background-size: 14px auto;
561 }
596 }
562
597
563 ul.messagelist li.error {
598 ul.messagelist li.error {
564 background: #ffefef url(../img/icon-no.svg) 40px 12px no-repeat;
599 background: var(--message-error-bg) url(../img/icon-no.svg) 40px 12px no-repeat;
565 background-size: 16px auto;
600 background-size: 16px auto;
566 }
601 }
567
602
568 .errornote {
603 .errornote {
569 font-size: 14px;
604 font-size: 0.875rem;
570 font-weight: 700;
605 font-weight: 700;
571 display: block;
606 display: block;
572 padding: 10px 12px;
607 padding: 10px 12px;
573 margin: 0 0 10px 0;
608 margin: 0 0 10px 0;
574 color: #ba2121;
609 color: var(--error-fg);
575 border: 1px solid #ba2121;
610 border: 1px solid var(--error-fg);
576 border-radius: 4px;
611 border-radius: 4px;
577 background-color: #fff;
612 background-color: var(--body-bg);
578 background-position: 5px 12px;
613 background-position: 5px 12px;
614 overflow-wrap: break-word;
579 }
615 }
580
616
581 ul.errorlist {
617 ul.errorlist {
582 margin: 0 0 4px;
618 margin: 0 0 4px;
583 padding: 0;
619 padding: 0;
584 color: #ba2121;
620 color: var(--error-fg);
585 background: #fff;
621 background: var(--body-bg);
586 }
622 }
587
623
588 ul.errorlist li {
624 ul.errorlist li {
589 font-size: 13px;
625 font-size: 0.8125rem;
590 display: block;
626 display: block;
591 margin-bottom: 4px;
627 margin-bottom: 4px;
628 overflow-wrap: break-word;
592 }
629 }
593
630
594 ul.errorlist li:first-child {
631 ul.errorlist li:first-child {
@@ -612,7 +649,7 td ul.errorlist li {
612 .form-row.errors {
649 .form-row.errors {
613 margin: 0;
650 margin: 0;
614 border: none;
651 border: none;
615 border-bottom: 1px solid #eee;
652 border-bottom: 1px solid var(--hairline-color);
616 background: none;
653 background: none;
617 }
654 }
618
655
@@ -620,46 +657,32 td ul.errorlist li {
620 padding-left: 0;
657 padding-left: 0;
621 }
658 }
622
659
623 .errors input, .errors select, .errors textarea {
660 .errors input, .errors select, .errors textarea,
624 border: 1px solid #ba2121;
661 td ul.errorlist + input, td ul.errorlist + select, td ul.errorlist + textarea {
625 }
662 border: 1px solid var(--error-fg);
626
627 div.system-message {
628 background: #ffc;
629 margin: 10px;
630 padding: 6px 8px;
631 font-size: .8em;
632 }
633
634 div.system-message p.system-message-title {
635 padding: 4px 5px 4px 25px;
636 margin: 0;
637 color: #c11;
638 background: #ffefef url(../img/icon-no.svg) 5px 5px no-repeat;
639 }
663 }
640
664
641 .description {
665 .description {
642 font-size: 12px;
666 font-size: 0.75rem;
643 padding: 5px 0 0 12px;
667 padding: 5px 0 0 12px;
644 }
668 }
645
669
646 /* BREADCRUMBS */
670 /* BREADCRUMBS */
647
671
648 div.breadcrumbs {
672 div.breadcrumbs {
649 background: #79aec8;
673 background: var(--breadcrumbs-bg);
650 padding: 10px 40px;
674 padding: 10px 40px;
651 border: none;
675 border: none;
652 font-size: 14px;
676 color: var(--breadcrumbs-fg);
653 color: #c4dce8;
654 text-align: left;
677 text-align: left;
655 }
678 }
656
679
657 div.breadcrumbs a {
680 div.breadcrumbs a {
658 color: #fff;
681 color: var(--breadcrumbs-link-fg);
659 }
682 }
660
683
661 div.breadcrumbs a:focus, div.breadcrumbs a:hover {
684 div.breadcrumbs a:focus, div.breadcrumbs a:hover {
662 color: #c4dce8;
685 color: var(--breadcrumbs-fg);
663 }
686 }
664
687
665 /* ACTION ICONS */
688 /* ACTION ICONS */
@@ -685,18 +708,18 div.breadcrumbs a:focus, div.breadcrumbs a:hover {
685 }
708 }
686
709
687 a.deletelink:link, a.deletelink:visited {
710 a.deletelink:link, a.deletelink:visited {
688 color: #CC3434;
711 color: #CC3434; /* XXX Probably unused? */
689 }
712 }
690
713
691 a.deletelink:focus, a.deletelink:hover {
714 a.deletelink:focus, a.deletelink:hover {
692 color: #993333;
715 color: #993333; /* XXX Probably unused? */
693 text-decoration: none;
716 text-decoration: none;
694 }
717 }
695
718
696 /* OBJECT TOOLS */
719 /* OBJECT TOOLS */
697
720
698 .object-tools {
721 .object-tools {
699 font-size: 10px;
722 font-size: 0.625rem;
700 font-weight: bold;
723 font-weight: bold;
701 padding-left: 0;
724 padding-left: 0;
702 float: right;
725 float: right;
@@ -704,14 +727,6 a.deletelink:focus, a.deletelink:hover {
704 margin-top: -48px;
727 margin-top: -48px;
705 }
728 }
706
729
707 .form-row .object-tools {
708 margin-top: 5px;
709 margin-bottom: 5px;
710 float: none;
711 height: 2em;
712 padding-left: 3.5em;
713 }
714
715 .object-tools li {
730 .object-tools li {
716 display: block;
731 display: block;
717 float: left;
732 float: left;
@@ -727,29 +742,29 a.deletelink:focus, a.deletelink:hover {
727 display: block;
742 display: block;
728 float: left;
743 float: left;
729 padding: 3px 12px;
744 padding: 3px 12px;
730 background: #999;
745 background: var(--object-tools-bg);
746 color: var(--object-tools-fg);
731 font-weight: 400;
747 font-weight: 400;
732 font-size: 11px;
748 font-size: 0.6875rem;
733 text-transform: uppercase;
749 text-transform: uppercase;
734 letter-spacing: 0.5px;
750 letter-spacing: 0.5px;
735 color: #fff;
736 }
751 }
737
752
738 .object-tools a:focus, .object-tools a:hover {
753 .object-tools a:focus, .object-tools a:hover {
739 background-color: #417690;
754 background-color: var(--object-tools-hover-bg);
740 }
755 }
741
756
742 .object-tools a:focus{
757 .object-tools a:focus{
743 text-decoration: none;
758 text-decoration: none;
744 }
759 }
745
760
746 .object-tools a.viewsitelink, .object-tools a.golink,.object-tools a.addlink {
761 .object-tools a.viewsitelink, .object-tools a.addlink {
747 background-repeat: no-repeat;
762 background-repeat: no-repeat;
748 background-position: right 7px center;
763 background-position: right 7px center;
749 padding-right: 26px;
764 padding-right: 26px;
750 }
765 }
751
766
752 .object-tools a.viewsitelink, .object-tools a.golink {
767 .object-tools a.viewsitelink {
753 background-image: url(../img/tooltag-arrowright.svg);
768 background-image: url(../img/tooltag-arrowright.svg);
754 }
769 }
755
770
@@ -759,14 +774,21 a.deletelink:focus, a.deletelink:hover {
759
774
760 /* OBJECT HISTORY */
775 /* OBJECT HISTORY */
761
776
762 table#change-history {
777 #change-history table {
763 width: 100%;
778 width: 100%;
764 }
779 }
765
780
766 table#change-history tbody th {
781 #change-history table tbody th {
767 width: 16em;
782 width: 16em;
768 }
783 }
769
784
785 #change-history .paginator {
786 color: var(--body-quiet-color);
787 border-bottom: 1px solid var(--hairline-color);
788 background: var(--body-bg);
789 overflow: hidden;
790 }
791
770 /* PAGE STRUCTURE */
792 /* PAGE STRUCTURE */
771
793
772 #container {
794 #container {
@@ -774,6 +796,23 table#change-history tbody th {
774 width: 100%;
796 width: 100%;
775 min-width: 980px;
797 min-width: 980px;
776 padding: 0;
798 padding: 0;
799 display: flex;
800 flex-direction: column;
801 height: 100%;
802 }
803
804 #container > div {
805 flex-shrink: 0;
806 }
807
808 #container > .main {
809 display: flex;
810 flex: 1 0 auto;
811 }
812
813 .main > .content {
814 flex: 1 0;
815 max-width: 100%;
777 }
816 }
778
817
779 #content {
818 #content {
@@ -834,13 +873,13 table#change-history tbody th {
834 justify-content: space-between;
873 justify-content: space-between;
835 align-items: center;
874 align-items: center;
836 padding: 10px 40px;
875 padding: 10px 40px;
837 background: #417690;
876 background: var(--header-bg);
838 color: #ffc;
877 color: var(--header-color);
839 overflow: hidden;
878 overflow: hidden;
840 }
879 }
841
880
842 #header a:link, #header a:visited {
881 #header a:link, #header a:visited, #logout-form button {
843 color: #fff;
882 color: var(--header-link-color);
844 }
883 }
845
884
846 #header a:focus , #header a:hover {
885 #header a:focus , #header a:hover {
@@ -855,51 +894,69 table#change-history tbody th {
855 padding: 0;
894 padding: 0;
856 margin: 0 20px 0 0;
895 margin: 0 20px 0 0;
857 font-weight: 300;
896 font-weight: 300;
858 font-size: 24px;
897 font-size: 1.5rem;
859 color: #f5dd5d;
898 color: var(--header-branding-color);
860 }
899 }
861
900
862 #branding h1, #branding h1 a:link, #branding h1 a:visited {
901 #branding h1 a:link, #branding h1 a:visited {
863 color: #f5dd5d;
902 color: var(--accent);
864 }
903 }
865
904
866 #branding h2 {
905 #branding h2 {
867 padding: 0 10px;
906 padding: 0 10px;
868 font-size: 14px;
907 font-size: 0.875rem;
869 margin: -8px 0 8px 0;
908 margin: -8px 0 8px 0;
870 font-weight: normal;
909 font-weight: normal;
871 color: #ffc;
910 color: var(--header-color);
872 }
911 }
873
912
874 #branding a:hover {
913 #branding a:hover {
875 text-decoration: none;
914 text-decoration: none;
876 }
915 }
877
916
917 #logout-form {
918 display: inline;
919 }
920
921 #logout-form button {
922 background: none;
923 border: 0;
924 cursor: pointer;
925 font-family: "Roboto","Lucida Grande","DejaVu Sans","Bitstream Vera Sans",Verdana,Arial,sans-serif;
926 }
927
878 #user-tools {
928 #user-tools {
879 float: right;
929 float: right;
880 padding: 0;
881 margin: 0 0 0 20px;
930 margin: 0 0 0 20px;
931 text-align: right;
932 }
933
934 #user-tools, #logout-form button{
935 padding: 0;
882 font-weight: 300;
936 font-weight: 300;
883 font-size: 11px;
937 font-size: 0.6875rem;
884 letter-spacing: 0.5px;
938 letter-spacing: 0.5px;
885 text-transform: uppercase;
939 text-transform: uppercase;
886 text-align: right;
887 }
940 }
888
941
889 #user-tools a {
942 #user-tools a, #logout-form button {
890 border-bottom: 1px solid rgba(255, 255, 255, 0.25);
943 border-bottom: 1px solid rgba(255, 255, 255, 0.25);
891 }
944 }
892
945
893 #user-tools a:focus, #user-tools a:hover {
946 #user-tools a:focus, #user-tools a:hover,
947 #logout-form button:active, #logout-form button:hover {
894 text-decoration: none;
948 text-decoration: none;
895 border-bottom-color: #79aec8;
949 border-bottom: 0;
896 color: #79aec8;
950 }
951
952 #logout-form button:active, #logout-form button:hover {
953 margin-bottom: 1px;
897 }
954 }
898
955
899 /* SIDEBAR */
956 /* SIDEBAR */
900
957
901 #content-related {
958 #content-related {
902 background: #f8f8f8;
959 background: var(--darkened-bg);
903 }
960 }
904
961
905 #content-related .module {
962 #content-related .module {
@@ -907,14 +964,13 table#change-history tbody th {
907 }
964 }
908
965
909 #content-related h3 {
966 #content-related h3 {
910 font-size: 14px;
967 color: var(--body-quiet-color);
911 color: #666;
912 padding: 0 16px;
968 padding: 0 16px;
913 margin: 0 0 16px;
969 margin: 0 0 16px;
914 }
970 }
915
971
916 #content-related h4 {
972 #content-related h4 {
917 font-size: 13px;
973 font-size: 0.8125rem;
918 }
974 }
919
975
920 #content-related p {
976 #content-related p {
@@ -937,22 +993,22 table#change-history tbody th {
937 background: none;
993 background: none;
938 padding: 16px;
994 padding: 16px;
939 margin-bottom: 16px;
995 margin-bottom: 16px;
940 border-bottom: 1px solid #eaeaea;
996 border-bottom: 1px solid var(--hairline-color);
941 font-size: 18px;
997 font-size: 1.125rem;
942 color: #333;
998 color: var(--body-fg);
943 }
999 }
944
1000
945 .delete-confirmation form input[type="submit"] {
1001 .delete-confirmation form input[type="submit"] {
946 background: #ba2121;
1002 background: var(--delete-button-bg);
947 border-radius: 4px;
1003 border-radius: 4px;
948 padding: 10px 15px;
1004 padding: 10px 15px;
949 color: #fff;
1005 color: var(--button-fg);
950 }
1006 }
951
1007
952 .delete-confirmation form input[type="submit"]:active,
1008 .delete-confirmation form input[type="submit"]:active,
953 .delete-confirmation form input[type="submit"]:focus,
1009 .delete-confirmation form input[type="submit"]:focus,
954 .delete-confirmation form input[type="submit"]:hover {
1010 .delete-confirmation form input[type="submit"]:hover {
955 background: #a41515;
1011 background: var(--delete-button-hover-bg);
956 }
1012 }
957
1013
958 .delete-confirmation form .cancel-link {
1014 .delete-confirmation form .cancel-link {
@@ -960,17 +1016,17 table#change-history tbody th {
960 vertical-align: middle;
1016 vertical-align: middle;
961 height: 15px;
1017 height: 15px;
962 line-height: 15px;
1018 line-height: 15px;
963 background: #ddd;
964 border-radius: 4px;
1019 border-radius: 4px;
965 padding: 10px 15px;
1020 padding: 10px 15px;
966 color: #333;
1021 color: var(--button-fg);
1022 background: var(--close-button-bg);
967 margin: 0 0 0 10px;
1023 margin: 0 0 0 10px;
968 }
1024 }
969
1025
970 .delete-confirmation form .cancel-link:active,
1026 .delete-confirmation form .cancel-link:active,
971 .delete-confirmation form .cancel-link:focus,
1027 .delete-confirmation form .cancel-link:focus,
972 .delete-confirmation form .cancel-link:hover {
1028 .delete-confirmation form .cancel-link:hover {
973 background: #ccc;
1029 background: var(--close-button-hover-bg);
974 }
1030 }
975
1031
976 /* POPUP */
1032 /* POPUP */
@@ -985,3 +1041,49 table#change-history tbody th {
985 .popup #header {
1041 .popup #header {
986 padding: 10px 20px;
1042 padding: 10px 20px;
987 }
1043 }
1044
1045 /* PAGINATOR */
1046
1047 .paginator {
1048 font-size: 0.8125rem;
1049 padding-top: 10px;
1050 padding-bottom: 10px;
1051 line-height: 22px;
1052 margin: 0;
1053 border-top: 1px solid var(--hairline-color);
1054 width: 100%;
1055 }
1056
1057 .paginator a:link, .paginator a:visited {
1058 padding: 2px 6px;
1059 background: var(--button-bg);
1060 text-decoration: none;
1061 color: var(--button-fg);
1062 }
1063
1064 .paginator a.showall {
1065 border: none;
1066 background: none;
1067 color: var(--link-fg);
1068 }
1069
1070 .paginator a.showall:focus, .paginator a.showall:hover {
1071 background: none;
1072 color: var(--link-hover-color);
1073 }
1074
1075 .paginator .end {
1076 margin-right: 6px;
1077 }
1078
1079 .paginator .this-page {
1080 padding: 2px 6px;
1081 font-weight: bold;
1082 font-size: 0.8125rem;
1083 vertical-align: top;
1084 }
1085
1086 .paginator a:focus, .paginator a:hover {
1087 color: white;
1088 background: var(--link-hover-color);
1089 }
@@ -1,8 +1,14
1 /* CHANGELISTS */
1 /* CHANGELISTS */
2
2
3 #changelist {
3 #changelist {
4 position: relative;
4 display: flex;
5 width: 100%;
5 align-items: flex-start;
6 justify-content: space-between;
7 }
8
9 #changelist .changelist-form-container {
10 flex: 1 1 auto;
11 min-width: 0;
6 }
12 }
7
13
8 #changelist table {
14 #changelist table {
@@ -21,7 +27,6
21
27
22 .change-list .filtered .results, .change-list .filtered .paginator,
28 .change-list .filtered .results, .change-list .filtered .paginator,
23 .filtered #toolbar, .filtered div.xfull {
29 .filtered #toolbar, .filtered div.xfull {
24 margin-right: 280px;
25 width: auto;
30 width: auto;
26 }
31 }
27
32
@@ -30,17 +35,18
30 }
35 }
31
36
32 #changelist-form .results {
37 #changelist-form .results {
33 overflow-x: auto;
38 overflow-x: auto;
39 width: 100%;
34 }
40 }
35
41
36 #changelist .toplinks {
42 #changelist .toplinks {
37 border-bottom: 1px solid #ddd;
43 border-bottom: 1px solid var(--hairline-color);
38 }
44 }
39
45
40 #changelist .paginator {
46 #changelist .paginator {
41 color: #666;
47 color: var(--body-quiet-color);
42 border-bottom: 1px solid #eee;
48 border-bottom: 1px solid var(--hairline-color);
43 background: #fff;
49 background: var(--body-bg);
44 overflow: hidden;
50 overflow: hidden;
45 }
51 }
46
52
@@ -62,76 +68,79
62 }
68 }
63
69
64 #changelist table tfoot {
70 #changelist table tfoot {
65 color: #666;
71 color: var(--body-quiet-color);
66 }
72 }
67
73
68 /* TOOLBAR */
74 /* TOOLBAR */
69
75
70 #changelist #toolbar {
76 #toolbar {
71 padding: 8px 10px;
77 padding: 8px 10px;
72 margin-bottom: 15px;
78 margin-bottom: 15px;
73 border-top: 1px solid #eee;
79 border-top: 1px solid var(--hairline-color);
74 border-bottom: 1px solid #eee;
80 border-bottom: 1px solid var(--hairline-color);
75 background: #f8f8f8;
81 background: var(--darkened-bg);
76 color: #666;
82 color: var(--body-quiet-color);
77 }
83 }
78
84
79 #changelist #toolbar form input {
85 #toolbar form input {
80 border-radius: 4px;
86 border-radius: 4px;
81 font-size: 14px;
87 font-size: 0.875rem;
82 padding: 5px;
88 padding: 5px;
83 color: #333;
89 color: var(--body-fg);
84 }
90 }
85
91
86 #changelist #toolbar form #searchbar {
92 #toolbar #searchbar {
87 height: 19px;
93 height: 19px;
88 border: 1px solid #ccc;
94 border: 1px solid var(--border-color);
89 padding: 2px 5px;
95 padding: 2px 5px;
90 margin: 0;
96 margin: 0;
91 vertical-align: top;
97 vertical-align: top;
92 font-size: 13px;
98 font-size: 0.8125rem;
99 max-width: 100%;
93 }
100 }
94
101
95 #changelist #toolbar form #searchbar:focus {
102 #toolbar #searchbar:focus {
96 border-color: #999;
103 border-color: var(--body-quiet-color);
97 }
104 }
98
105
99 #changelist #toolbar form input[type="submit"] {
106 #toolbar form input[type="submit"] {
100 border: 1px solid #ccc;
107 border: 1px solid var(--border-color);
101 padding: 2px 10px;
108 font-size: 0.8125rem;
109 padding: 4px 8px;
102 margin: 0;
110 margin: 0;
103 vertical-align: middle;
111 vertical-align: middle;
104 background: #fff;
112 background: var(--body-bg);
105 box-shadow: 0 -15px 20px -10px rgba(0, 0, 0, 0.15) inset;
113 box-shadow: 0 -15px 20px -10px rgba(0, 0, 0, 0.15) inset;
106 cursor: pointer;
114 cursor: pointer;
107 color: #333;
115 color: var(--body-fg);
108 }
116 }
109
117
110 #changelist #toolbar form input[type="submit"]:focus,
118 #toolbar form input[type="submit"]:focus,
111 #changelist #toolbar form input[type="submit"]:hover {
119 #toolbar form input[type="submit"]:hover {
112 border-color: #999;
120 border-color: var(--body-quiet-color);
113 }
121 }
114
122
115 #changelist #changelist-search img {
123 #changelist-search img {
116 vertical-align: middle;
124 vertical-align: middle;
117 margin-right: 4px;
125 margin-right: 4px;
118 }
126 }
119
127
128 #changelist-search .help {
129 word-break: break-word;
130 }
131
120 /* FILTER COLUMN */
132 /* FILTER COLUMN */
121
133
122 #changelist-filter {
134 #changelist-filter {
123 position: absolute;
135 flex: 0 0 240px;
124 top: 0;
136 order: 1;
125 right: 0;
137 background: var(--darkened-bg);
126 z-index: 1000;
127 width: 240px;
128 background: #f8f8f8;
129 border-left: none;
138 border-left: none;
130 margin: 0;
139 margin: 0 0 0 30px;
131 }
140 }
132
141
133 #changelist-filter h2 {
142 #changelist-filter h2 {
134 font-size: 14px;
143 font-size: 0.875rem;
135 text-transform: uppercase;
144 text-transform: uppercase;
136 letter-spacing: 0.5px;
145 letter-spacing: 0.5px;
137 padding: 5px 15px;
146 padding: 5px 15px;
@@ -139,22 +148,43
139 border-bottom: none;
148 border-bottom: none;
140 }
149 }
141
150
142 #changelist-filter h3 {
151 #changelist-filter h3,
152 #changelist-filter details summary {
143 font-weight: 400;
153 font-weight: 400;
144 font-size: 14px;
145 padding: 0 15px;
154 padding: 0 15px;
146 margin-bottom: 10px;
155 margin-bottom: 10px;
147 }
156 }
148
157
158 #changelist-filter details summary > * {
159 display: inline;
160 }
161
162 #changelist-filter details > summary {
163 list-style-type: none;
164 }
165
166 #changelist-filter details > summary::-webkit-details-marker {
167 display: none;
168 }
169
170 #changelist-filter details > summary::before {
171 content: '→';
172 font-weight: bold;
173 color: var(--link-hover-color);
174 }
175
176 #changelist-filter details[open] > summary::before {
177 content: '↓';
178 }
179
149 #changelist-filter ul {
180 #changelist-filter ul {
150 margin: 5px 0;
181 margin: 5px 0;
151 padding: 0 15px 15px;
182 padding: 0 15px 15px;
152 border-bottom: 1px solid #eaeaea;
183 border-bottom: 1px solid var(--hairline-color);
153 }
184 }
154
185
155 #changelist-filter ul:last-child {
186 #changelist-filter ul:last-child {
156 border-bottom: none;
187 border-bottom: none;
157 padding-bottom: none;
158 }
188 }
159
189
160 #changelist-filter li {
190 #changelist-filter li {
@@ -165,25 +195,30
165
195
166 #changelist-filter a {
196 #changelist-filter a {
167 display: block;
197 display: block;
168 color: #999;
198 color: var(--body-quiet-color);
169 text-overflow: ellipsis;
199 word-break: break-word;
170 overflow-x: hidden;
171 }
200 }
172
201
173 #changelist-filter li.selected {
202 #changelist-filter li.selected {
174 border-left: 5px solid #eaeaea;
203 border-left: 5px solid var(--hairline-color);
175 padding-left: 10px;
204 padding-left: 10px;
176 margin-left: -15px;
205 margin-left: -15px;
177 }
206 }
178
207
179 #changelist-filter li.selected a {
208 #changelist-filter li.selected a {
180 color: #5b80b2;
209 color: var(--link-selected-fg);
181 }
210 }
182
211
183 #changelist-filter a:focus, #changelist-filter a:hover,
212 #changelist-filter a:focus, #changelist-filter a:hover,
184 #changelist-filter li.selected a:focus,
213 #changelist-filter li.selected a:focus,
185 #changelist-filter li.selected a:hover {
214 #changelist-filter li.selected a:hover {
186 color: #036;
215 color: var(--link-hover-color);
216 }
217
218 #changelist-filter #changelist-filter-clear a {
219 font-size: 0.8125rem;
220 padding-bottom: 10px;
221 border-bottom: 1px solid var(--hairline-color);
187 }
222 }
188
223
189 /* DATE DRILLDOWN */
224 /* DATE DRILLDOWN */
@@ -204,64 +239,17
204 }
239 }
205
240
206 .change-list ul.toplinks .date-back a {
241 .change-list ul.toplinks .date-back a {
207 color: #999;
242 color: var(--body-quiet-color);
208 }
243 }
209
244
210 .change-list ul.toplinks .date-back a:focus,
245 .change-list ul.toplinks .date-back a:focus,
211 .change-list ul.toplinks .date-back a:hover {
246 .change-list ul.toplinks .date-back a:hover {
212 color: #036;
247 color: var(--link-hover-color);
213 }
214
215 /* PAGINATOR */
216
217 .paginator {
218 font-size: 13px;
219 padding-top: 10px;
220 padding-bottom: 10px;
221 line-height: 22px;
222 margin: 0;
223 border-top: 1px solid #ddd;
224 }
225
226 .paginator a:link, .paginator a:visited {
227 padding: 2px 6px;
228 background: #79aec8;
229 text-decoration: none;
230 color: #fff;
231 }
232
233 .paginator a.showall {
234 padding: 0;
235 border: none;
236 background: none;
237 color: #5b80b2;
238 }
239
240 .paginator a.showall:focus, .paginator a.showall:hover {
241 background: none;
242 color: #036;
243 }
244
245 .paginator .end {
246 margin-right: 6px;
247 }
248
249 .paginator .this-page {
250 padding: 2px 6px;
251 font-weight: bold;
252 font-size: 13px;
253 vertical-align: top;
254 }
255
256 .paginator a:focus, .paginator a:hover {
257 color: white;
258 background: #036;
259 }
248 }
260
249
261 /* ACTIONS */
250 /* ACTIONS */
262
251
263 .filtered .actions {
252 .filtered .actions {
264 margin-right: 280px;
265 border-right: none;
253 border-right: none;
266 }
254 }
267
255
@@ -271,31 +259,25
271 }
259 }
272
260
273 #changelist table tbody tr.selected {
261 #changelist table tbody tr.selected {
274 background-color: #FFFFCC;
262 background-color: var(--selected-row);
275 }
263 }
276
264
277 #changelist .actions {
265 #changelist .actions {
278 padding: 10px;
266 padding: 10px;
279 background: #fff;
267 background: var(--body-bg);
280 border-top: none;
268 border-top: none;
281 border-bottom: none;
269 border-bottom: none;
282 line-height: 24px;
270 line-height: 24px;
283 color: #999;
271 color: var(--body-quiet-color);
284 }
272 width: 100%;
285
286 #changelist .actions.selected {
287 background: #fffccf;
288 border-top: 1px solid #fffee8;
289 border-bottom: 1px solid #edecd6;
290 }
273 }
291
274
292 #changelist .actions span.all,
275 #changelist .actions span.all,
293 #changelist .actions span.action-counter,
276 #changelist .actions span.action-counter,
294 #changelist .actions span.clear,
277 #changelist .actions span.clear,
295 #changelist .actions span.question {
278 #changelist .actions span.question {
296 font-size: 13px;
279 font-size: 0.8125rem;
297 margin: 0 0.5em;
280 margin: 0 0.5em;
298 display: none;
299 }
281 }
300
282
301 #changelist .actions:last-child {
283 #changelist .actions:last-child {
@@ -305,40 +287,39
305 #changelist .actions select {
287 #changelist .actions select {
306 vertical-align: top;
288 vertical-align: top;
307 height: 24px;
289 height: 24px;
308 background: none;
290 color: var(--body-fg);
309 color: #000;
291 border: 1px solid var(--border-color);
310 border: 1px solid #ccc;
311 border-radius: 4px;
292 border-radius: 4px;
312 font-size: 14px;
293 font-size: 0.875rem;
313 padding: 0 0 0 4px;
294 padding: 0 0 0 4px;
314 margin: 0;
295 margin: 0;
315 margin-left: 10px;
296 margin-left: 10px;
316 }
297 }
317
298
318 #changelist .actions select:focus {
299 #changelist .actions select:focus {
319 border-color: #999;
300 border-color: var(--body-quiet-color);
320 }
301 }
321
302
322 #changelist .actions label {
303 #changelist .actions label {
323 display: inline-block;
304 display: inline-block;
324 vertical-align: middle;
305 vertical-align: middle;
325 font-size: 13px;
306 font-size: 0.8125rem;
326 }
307 }
327
308
328 #changelist .actions .button {
309 #changelist .actions .button {
329 font-size: 13px;
310 font-size: 0.8125rem;
330 border: 1px solid #ccc;
311 border: 1px solid var(--border-color);
331 border-radius: 4px;
312 border-radius: 4px;
332 background: #fff;
313 background: var(--body-bg);
333 box-shadow: 0 -15px 20px -10px rgba(0, 0, 0, 0.15) inset;
314 box-shadow: 0 -15px 20px -10px rgba(0, 0, 0, 0.15) inset;
334 cursor: pointer;
315 cursor: pointer;
335 height: 24px;
316 height: 24px;
336 line-height: 1;
317 line-height: 1;
337 padding: 4px 8px;
318 padding: 4px 8px;
338 margin: 0;
319 margin: 0;
339 color: #333;
320 color: var(--body-fg);
340 }
321 }
341
322
342 #changelist .actions .button:focus, #changelist .actions .button:hover {
323 #changelist .actions .button:focus, #changelist .actions .button:hover {
343 border-color: #999;
324 border-color: var(--body-quiet-color);
344 }
325 }
@@ -23,5 +23,4 ul.actionlist li {
23 list-style-type: none;
23 list-style-type: none;
24 overflow: hidden;
24 overflow: hidden;
25 text-overflow: ellipsis;
25 text-overflow: ellipsis;
26 -o-text-overflow: ellipsis;
27 }
26 }
@@ -5,8 +5,8
5 .form-row {
5 .form-row {
6 overflow: hidden;
6 overflow: hidden;
7 padding: 10px;
7 padding: 10px;
8 font-size: 13px;
8 font-size: 0.8125rem;
9 border-bottom: 1px solid #eee;
9 border-bottom: 1px solid var(--hairline-color);
10 }
10 }
11
11
12 .form-row img, .form-row input {
12 .form-row img, .form-row input {
@@ -22,35 +22,34 form .form-row p {
22 padding-left: 0;
22 padding-left: 0;
23 }
23 }
24
24
25 .hidden {
26 display: none;
27 }
28
29 /* FORM LABELS */
25 /* FORM LABELS */
30
26
31 label {
27 label {
32 font-weight: normal;
28 font-weight: normal;
33 color: #666;
29 color: var(--body-quiet-color);
34 font-size: 13px;
30 font-size: 0.8125rem;
35 }
31 }
36
32
37 .required label, label.required {
33 .required label, label.required {
38 font-weight: bold;
34 font-weight: bold;
39 color: #333;
35 color: var(--body-fg);
40 }
36 }
41
37
42 /* RADIO BUTTONS */
38 /* RADIO BUTTONS */
43
39
44 form ul.radiolist li {
40 form div.radiolist div {
45 list-style-type: none;
41 padding-right: 7px;
46 }
42 }
47
43
48 form ul.radiolist label {
44 form div.radiolist.inline div {
49 float: none;
45 display: inline-block;
50 display: inline;
46 }
47
48 form div.radiolist label {
49 width: auto;
51 }
50 }
52
51
53 form ul.radiolist input[type="radio"] {
52 form div.radiolist input[type="radio"] {
54 margin: -2px 4px 0 0;
53 margin: -2px 4px 0 0;
55 padding: 0;
54 padding: 0;
56 }
55 }
@@ -88,6 +87,7 form ul.inline li {
88 margin-top: 0;
87 margin-top: 0;
89 margin-bottom: 0;
88 margin-bottom: 0;
90 margin-left: 170px;
89 margin-left: 170px;
90 overflow-wrap: break-word;
91 }
91 }
92
92
93 .aligned ul label {
93 .aligned ul label {
@@ -109,7 +109,7 form .aligned ul {
109 padding-left: 10px;
109 padding-left: 10px;
110 }
110 }
111
111
112 form .aligned ul.radiolist {
112 form .aligned div.radiolist {
113 display: inline-block;
113 display: inline-block;
114 margin: 0;
114 margin: 0;
115 padding: 0;
115 padding: 0;
@@ -219,24 +219,24 fieldset.collapsed h2, fieldset.collapsed {
219 }
219 }
220
220
221 fieldset.collapsed {
221 fieldset.collapsed {
222 border: 1px solid #eee;
222 border: 1px solid var(--hairline-color);
223 border-radius: 4px;
223 border-radius: 4px;
224 overflow: hidden;
224 overflow: hidden;
225 }
225 }
226
226
227 fieldset.collapsed h2 {
227 fieldset.collapsed h2 {
228 background: #f8f8f8;
228 background: var(--darkened-bg);
229 color: #666;
229 color: var(--body-quiet-color);
230 }
230 }
231
231
232 fieldset .collapse-toggle {
232 fieldset .collapse-toggle {
233 color: #fff;
233 color: var(--header-link-color);
234 }
234 }
235
235
236 fieldset.collapsed .collapse-toggle {
236 fieldset.collapsed .collapse-toggle {
237 background: transparent;
237 background: transparent;
238 display: inline;
238 display: inline;
239 color: #447e9b;
239 color: var(--link-fg);
240 }
240 }
241
241
242 /* MONOSPACE TEXTAREAS */
242 /* MONOSPACE TEXTAREAS */
@@ -248,10 +248,10 fieldset.monospace textarea {
248 /* SUBMIT ROW */
248 /* SUBMIT ROW */
249
249
250 .submit-row {
250 .submit-row {
251 padding: 12px 14px;
251 padding: 12px 14px 7px;
252 margin: 0 0 20px;
252 margin: 0 0 20px;
253 background: #f8f8f8;
253 background: var(--darkened-bg);
254 border: 1px solid #eee;
254 border: 1px solid var(--hairline-color);
255 border-radius: 4px;
255 border-radius: 4px;
256 text-align: right;
256 text-align: right;
257 overflow: hidden;
257 overflow: hidden;
@@ -264,11 +264,11 body.popup .submit-row {
264 .submit-row input {
264 .submit-row input {
265 height: 35px;
265 height: 35px;
266 line-height: 15px;
266 line-height: 15px;
267 margin: 0 0 0 5px;
267 margin: 0 0 5px 5px;
268 }
268 }
269
269
270 .submit-row input.default {
270 .submit-row input.default {
271 margin: 0 0 0 8px;
271 margin: 0 0 5px 8px;
272 text-transform: uppercase;
272 text-transform: uppercase;
273 }
273 }
274
274
@@ -283,35 +283,36 body.popup .submit-row {
283
283
284 .submit-row a.deletelink {
284 .submit-row a.deletelink {
285 display: block;
285 display: block;
286 background: #ba2121;
286 background: var(--delete-button-bg);
287 border-radius: 4px;
287 border-radius: 4px;
288 padding: 10px 15px;
288 padding: 10px 15px;
289 height: 15px;
289 height: 15px;
290 line-height: 15px;
290 line-height: 15px;
291 color: #fff;
291 margin-bottom: 5px;
292 color: var(--button-fg);
292 }
293 }
293
294
294 .submit-row a.closelink {
295 .submit-row a.closelink {
295 display: inline-block;
296 display: inline-block;
296 background: #bbbbbb;
297 background: var(--close-button-bg);
297 border-radius: 4px;
298 border-radius: 4px;
298 padding: 10px 15px;
299 padding: 10px 15px;
299 height: 15px;
300 height: 15px;
300 line-height: 15px;
301 line-height: 15px;
301 margin: 0 0 0 5px;
302 margin: 0 0 0 5px;
302 color: #fff;
303 color: var(--button-fg);
303 }
304 }
304
305
305 .submit-row a.deletelink:focus,
306 .submit-row a.deletelink:focus,
306 .submit-row a.deletelink:hover,
307 .submit-row a.deletelink:hover,
307 .submit-row a.deletelink:active {
308 .submit-row a.deletelink:active {
308 background: #a41515;
309 background: var(--delete-button-hover-bg);
309 }
310 }
310
311
311 .submit-row a.closelink:focus,
312 .submit-row a.closelink:focus,
312 .submit-row a.closelink:hover,
313 .submit-row a.closelink:hover,
313 .submit-row a.closelink:active {
314 .submit-row a.closelink:active {
314 background: #aaaaaa;
315 background: var(--close-button-hover-bg);
315 }
316 }
316
317
317 /* CUSTOM FORM FIELDS */
318 /* CUSTOM FORM FIELDS */
@@ -353,10 +354,6 body.popup .submit-row {
353 width: 2.2em;
354 width: 2.2em;
354 }
355 }
355
356
356 .vTextField, .vUUIDField {
357 width: 20em;
358 }
359
360 .vIntegerField {
357 .vIntegerField {
361 width: 5em;
358 width: 5em;
362 }
359 }
@@ -369,6 +366,10 body.popup .submit-row {
369 width: 5em;
366 width: 5em;
370 }
367 }
371
368
369 .vTextField, .vUUIDField {
370 width: 20em;
371 }
372
372 /* INLINES */
373 /* INLINES */
373
374
374 .inline-group {
375 .inline-group {
@@ -390,12 +391,12 body.popup .submit-row {
390
391
391 .inline-related h3 {
392 .inline-related h3 {
392 margin: 0;
393 margin: 0;
393 color: #666;
394 color: var(--body-quiet-color);
394 padding: 5px;
395 padding: 5px;
395 font-size: 13px;
396 font-size: 0.8125rem;
396 background: #f8f8f8;
397 background: var(--darkened-bg);
397 border-top: 1px solid #eee;
398 border-top: 1px solid var(--hairline-color);
398 border-bottom: 1px solid #eee;
399 border-bottom: 1px solid var(--hairline-color);
399 }
400 }
400
401
401 .inline-related h3 span.delete {
402 .inline-related h3 span.delete {
@@ -404,12 +405,12 body.popup .submit-row {
404
405
405 .inline-related h3 span.delete label {
406 .inline-related h3 span.delete label {
406 margin-left: 2px;
407 margin-left: 2px;
407 font-size: 11px;
408 font-size: 0.6875rem;
408 }
409 }
409
410
410 .inline-related fieldset {
411 .inline-related fieldset {
411 margin: 0;
412 margin: 0;
412 background: #fff;
413 background: var(--body-bg);
413 border: none;
414 border: none;
414 width: 100%;
415 width: 100%;
415 }
416 }
@@ -417,11 +418,11 body.popup .submit-row {
417 .inline-related fieldset.module h3 {
418 .inline-related fieldset.module h3 {
418 margin: 0;
419 margin: 0;
419 padding: 2px 5px 3px 5px;
420 padding: 2px 5px 3px 5px;
420 font-size: 11px;
421 font-size: 0.6875rem;
421 text-align: left;
422 text-align: left;
422 font-weight: bold;
423 font-weight: bold;
423 background: #bcd;
424 background: #bcd;
424 color: #fff;
425 color: var(--body-bg);
425 }
426 }
426
427
427 .inline-group .tabular fieldset.module {
428 .inline-group .tabular fieldset.module {
@@ -430,6 +431,7 body.popup .submit-row {
430
431
431 .inline-related.tabular fieldset.module table {
432 .inline-related.tabular fieldset.module table {
432 width: 100%;
433 width: 100%;
434 overflow-x: scroll;
433 }
435 }
434
436
435 .last-related fieldset {
437 .last-related fieldset {
@@ -457,9 +459,9 body.popup .submit-row {
457 height: 1.1em;
459 height: 1.1em;
458 padding: 2px 9px;
460 padding: 2px 9px;
459 overflow: hidden;
461 overflow: hidden;
460 font-size: 9px;
462 font-size: 0.5625rem;
461 font-weight: bold;
463 font-weight: bold;
462 color: #666;
464 color: var(--body-quiet-color);
463 _width: 700px;
465 _width: 700px;
464 }
466 }
465
467
@@ -476,15 +478,15 body.popup .submit-row {
476
478
477 .inline-group div.add-row,
479 .inline-group div.add-row,
478 .inline-group .tabular tr.add-row td {
480 .inline-group .tabular tr.add-row td {
479 color: #666;
481 color: var(--body-quiet-color);
480 background: #f8f8f8;
482 background: var(--darkened-bg);
481 padding: 8px 10px;
483 padding: 8px 10px;
482 border-bottom: 1px solid #eee;
484 border-bottom: 1px solid var(--hairline-color);
483 }
485 }
484
486
485 .inline-group .tabular tr.add-row td {
487 .inline-group .tabular tr.add-row td {
486 padding: 8px 10px;
488 padding: 8px 10px;
487 border-bottom: 1px solid #eee;
489 border-bottom: 1px solid var(--hairline-color);
488 }
490 }
489
491
490 .inline-group ul.tools a.add,
492 .inline-group ul.tools a.add,
@@ -492,7 +494,7 body.popup .submit-row {
492 .inline-group .tabular tr.add-row td a {
494 .inline-group .tabular tr.add-row td a {
493 background: url(../img/icon-addlink.svg) 0 1px no-repeat;
495 background: url(../img/icon-addlink.svg) 0 1px no-repeat;
494 padding-left: 16px;
496 padding-left: 16px;
495 font-size: 12px;
497 font-size: 0.75rem;
496 }
498 }
497
499
498 .empty-form {
500 .empty-form {
@@ -501,7 +503,7 body.popup .submit-row {
501
503
502 /* RELATED FIELD ADD ONE / LOOKUP */
504 /* RELATED FIELD ADD ONE / LOOKUP */
503
505
504 .add-another, .related-lookup {
506 .related-lookup {
505 margin-left: 5px;
507 margin-left: 5px;
506 display: inline-block;
508 display: inline-block;
507 vertical-align: middle;
509 vertical-align: middle;
@@ -509,12 +511,6 body.popup .submit-row {
509 background-size: 14px;
511 background-size: 14px;
510 }
512 }
511
513
512 .add-another {
513 width: 16px;
514 height: 16px;
515 background-image: url(../img/icon-addlink.svg);
516 }
517
518 .related-lookup {
514 .related-lookup {
519 width: 16px;
515 width: 16px;
520 height: 16px;
516 height: 16px;
@@ -1,7 +1,8
1 /* LOGIN FORM */
1 /* LOGIN FORM */
2
2
3 body.login {
3 .login {
4 background: #f8f8f8;
4 background: var(--darkened-bg);
5 height: auto;
5 }
6 }
6
7
7 .login #header {
8 .login #header {
@@ -11,11 +12,12 body.login {
11 }
12 }
12
13
13 .login #header h1 {
14 .login #header h1 {
14 font-size: 18px;
15 font-size: 1.125rem;
16 margin: 0;
15 }
17 }
16
18
17 .login #header h1 a {
19 .login #header h1 a {
18 color: #fff;
20 color: var(--header-link-color);
19 }
21 }
20
22
21 .login #content {
23 .login #content {
@@ -23,55 +25,35 body.login {
23 }
25 }
24
26
25 .login #container {
27 .login #container {
26 background: #fff;
28 background: var(--body-bg);
27 border: 1px solid #eaeaea;
29 border: 1px solid var(--hairline-color);
28 border-radius: 4px;
30 border-radius: 4px;
29 overflow: hidden;
31 overflow: hidden;
30 width: 28em;
32 width: 28em;
31 min-width: 300px;
33 min-width: 300px;
32 margin: 100px auto;
34 margin: 100px auto;
33 }
35 height: auto;
34
35 .login #content-main {
36 width: 100%;
37 }
36 }
38
37
39 .login .form-row {
38 .login .form-row {
40 padding: 4px 0;
39 padding: 4px 0;
41 float: left;
42 width: 100%;
43 border-bottom: none;
44 }
40 }
45
41
46 .login .form-row label {
42 .login .form-row label {
47 padding-right: 0.5em;
43 display: block;
48 line-height: 2em;
44 line-height: 2em;
49 font-size: 1em;
50 clear: both;
51 color: #333;
52 }
45 }
53
46
54 .login .form-row #id_username, .login .form-row #id_password {
47 .login .form-row #id_username, .login .form-row #id_password {
55 clear: both;
56 padding: 8px;
48 padding: 8px;
57 width: 100%;
49 width: 100%;
58 -webkit-box-sizing: border-box;
50 box-sizing: border-box;
59 -moz-box-sizing: border-box;
60 box-sizing: border-box;
61 }
62
63 .login span.help {
64 font-size: 10px;
65 display: block;
66 }
51 }
67
52
68 .login .submit-row {
53 .login .submit-row {
69 clear: both;
54 padding: 1em 0 0 0;
70 padding: 1em 0 0 9.4em;
71 margin: 0;
55 margin: 0;
72 border: none;
56 text-align: center;
73 background: none;
74 text-align: left;
75 }
57 }
76
58
77 .login .password-reset-link {
59 .login .password-reset-link {
@@ -14,11 +14,11 input[type="submit"], button {
14
14
15 td, th {
15 td, th {
16 padding: 10px;
16 padding: 10px;
17 font-size: 14px;
17 font-size: 0.875rem;
18 }
18 }
19
19
20 .small {
20 .small {
21 font-size: 12px;
21 font-size: 0.75rem;
22 }
22 }
23
23
24 /* Layout */
24 /* Layout */
@@ -28,7 +28,7 input[type="submit"], button {
28 }
28 }
29
29
30 #content {
30 #content {
31 padding: 20px 30px 30px;
31 padding: 15px 20px 20px;
32 }
32 }
33
33
34 div.breadcrumbs {
34 div.breadcrumbs {
@@ -45,7 +45,6 input[type="submit"], button {
45
45
46 #branding h1 {
46 #branding h1 {
47 margin: 0 0 8px;
47 margin: 0 0 8px;
48 font-size: 20px;
49 line-height: 1.2;
48 line-height: 1.2;
50 }
49 }
51
50
@@ -88,21 +87,19 input[type="submit"], button {
88 }
87 }
89
88
90 td .changelink, td .addlink {
89 td .changelink, td .addlink {
91 font-size: 13px;
90 font-size: 0.8125rem;
92 }
91 }
93
92
94 /* Changelist */
93 /* Changelist */
95
94
96 #changelist #toolbar {
95 #toolbar {
97 border: none;
96 border: none;
98 padding: 15px;
97 padding: 15px;
99 }
98 }
100
99
101 #changelist-search > div {
100 #changelist-search > div {
102 display: -webkit-flex;
103 display: flex;
101 display: flex;
104 -webkit-flex-wrap: wrap;
102 flex-wrap: nowrap;
105 flex-wrap: wrap;
106 max-width: 480px;
103 max-width: 480px;
107 }
104 }
108
105
@@ -110,16 +107,20 input[type="submit"], button {
110 line-height: 22px;
107 line-height: 22px;
111 }
108 }
112
109
113 #changelist #toolbar form #searchbar {
110 #toolbar form #searchbar {
114 -webkit-flex: 1 0 auto;
115 flex: 1 0 auto;
111 flex: 1 0 auto;
116 width: 0;
112 width: 0;
117 height: 22px;
113 height: 22px;
118 margin: 0 10px 0 6px;
114 margin: 0 10px 0 6px;
119 }
115 }
120
116
117 #toolbar form input[type=submit] {
118 flex: 0 1 auto;
119 }
120
121 #changelist-search .quiet {
121 #changelist-search .quiet {
122 width: 100%;
122 width: 0;
123 flex: 1 0 auto;
123 margin: 5px 0 0 25px;
124 margin: 5px 0 0 25px;
124 }
125 }
125
126
@@ -129,16 +130,12 input[type="submit"], button {
129 padding: 15px 0;
130 padding: 15px 0;
130 }
131 }
131
132
132 #changelist .actions.selected {
133 border: none;
134 }
135
136 #changelist .actions label {
133 #changelist .actions label {
137 display: flex;
134 display: flex;
138 }
135 }
139
136
140 #changelist .actions select {
137 #changelist .actions select {
141 background: #fff;
138 background: var(--body-bg);
142 }
139 }
143
140
144 #changelist .actions .button {
141 #changelist .actions .button {
@@ -150,24 +147,21 input[type="submit"], button {
150 #changelist .actions span.clear,
147 #changelist .actions span.clear,
151 #changelist .actions span.question,
148 #changelist .actions span.question,
152 #changelist .actions span.action-counter {
149 #changelist .actions span.action-counter {
153 font-size: 11px;
150 font-size: 0.6875rem;
154 margin: 0 10px 0 0;
151 margin: 0 10px 0 0;
155 }
152 }
156
153
157 #changelist-filter {
154 #changelist-filter {
158 width: 200px;
155 flex-basis: 200px;
159 }
156 }
160
157
161 .change-list .filtered .results,
158 .change-list .filtered .results,
162 .change-list .filtered .paginator,
159 .change-list .filtered .paginator,
163 .filtered #toolbar,
160 .filtered #toolbar,
164 .filtered .actions,
161 .filtered .actions,
165 .filtered div.xfull {
166 margin-right: 230px;
167 }
168
162
169 #changelist .paginator {
163 #changelist .paginator {
170 border-top-color: #eee;
164 border-top-color: var(--hairline-color); /* XXX Is this used at all? */
171 }
165 }
172
166
173 #changelist .results + .paginator {
167 #changelist .results + .paginator {
@@ -177,7 +171,7 input[type="submit"], button {
177 /* Forms */
171 /* Forms */
178
172
179 label {
173 label {
180 font-size: 14px;
174 font-size: 0.875rem;
181 }
175 }
182
176
183 .form-row input[type=text],
177 .form-row input[type=text],
@@ -193,7 +187,7 input[type="submit"], button {
193 margin: 0;
187 margin: 0;
194 padding: 6px 8px;
188 padding: 6px 8px;
195 min-height: 36px;
189 min-height: 36px;
196 font-size: 14px;
190 font-size: 0.875rem;
197 }
191 }
198
192
199 .form-row select {
193 .form-row select {
@@ -214,11 +208,11 input[type="submit"], button {
214 fieldset .fieldBox + .fieldBox {
208 fieldset .fieldBox + .fieldBox {
215 margin-top: 10px;
209 margin-top: 10px;
216 padding-top: 10px;
210 padding-top: 10px;
217 border-top: 1px solid #eee;
211 border-top: 1px solid var(--hairline-color);
218 }
212 }
219
213
220 textarea {
214 textarea {
221 max-width: 518px;
215 max-width: 100%;
222 max-height: 120px;
216 max-height: 120px;
223 }
217 }
224
218
@@ -226,7 +220,6 input[type="submit"], button {
226 padding-top: 6px;
220 padding-top: 6px;
227 }
221 }
228
222
229 .aligned .add-another,
230 .aligned .related-lookup,
223 .aligned .related-lookup,
231 .aligned .datetimeshortcuts,
224 .aligned .datetimeshortcuts,
232 .aligned .related-lookup + strong {
225 .aligned .related-lookup + strong {
@@ -234,10 +227,26 input[type="submit"], button {
234 margin-left: 15px;
227 margin-left: 15px;
235 }
228 }
236
229
237 form .aligned ul.radiolist {
230 form .aligned div.radiolist {
238 margin-left: 2px;
231 margin-left: 2px;
239 }
232 }
240
233
234 .submit-row {
235 padding: 8px 8px 3px 8px;
236 }
237
238 .submit-row a.deletelink {
239 padding: 10px 7px;
240 }
241
242 .submit-row input.default {
243 margin: 0 0 5px 5px;
244 }
245
246 .button, input[type=submit], input[type=button], .submit-row input, a.button {
247 padding: 7px;
248 }
249
241 /* Related widget */
250 /* Related widget */
242
251
243 .related-widget-wrapper {
252 .related-widget-wrapper {
@@ -354,6 +363,14 input[type="submit"], button {
354 }
363 }
355
364
356 .stacked .active.selector-add {
365 .stacked .active.selector-add {
366 background-position: 0 -40px;
367 }
368
369 .active.selector-add:focus, .active.selector-add:hover {
370 background-position: 0 -140px;
371 }
372
373 .stacked .active.selector-add:focus, .stacked .active.selector-add:hover {
357 background-position: 0 -60px;
374 background-position: 0 -60px;
358 }
375 }
359
376
@@ -362,6 +379,14 input[type="submit"], button {
362 }
379 }
363
380
364 .stacked .active.selector-remove {
381 .stacked .active.selector-remove {
382 background-position: 0 0;
383 }
384
385 .active.selector-remove:focus, .active.selector-remove:hover {
386 background-position: 0 -100px;
387 }
388
389 .stacked .active.selector-remove:focus, .stacked .active.selector-remove:hover {
365 background-position: 0 -20px;
390 background-position: 0 -20px;
366 }
391 }
367
392
@@ -379,17 +404,21 input[type="submit"], button {
379 }
404 }
380
405
381 .datetime span {
406 .datetime span {
382 font-size: 13px;
407 font-size: 0.8125rem;
383 }
408 }
384
409
385 .datetime .timezonewarning {
410 .datetime .timezonewarning {
386 display: block;
411 display: block;
387 font-size: 11px;
412 font-size: 0.6875rem;
388 color: #999;
413 color: var(--body-quiet-color);
389 }
414 }
390
415
391 .datetimeshortcuts {
416 .datetimeshortcuts {
392 color: #ccc;
417 color: var(--border-color); /* XXX Redundant, .datetime span also sets #ccc */
418 }
419
420 .form-row .datetime input.vDateField, .form-row .datetime input.vTimeField {
421 width: 75%;
393 }
422 }
394
423
395 .inline-group {
424 .inline-group {
@@ -478,31 +507,22 input[type="submit"], button {
478
507
479 #content-related .module h2 {
508 #content-related .module h2 {
480 padding: 10px 15px;
509 padding: 10px 15px;
481 font-size: 16px;
510 font-size: 1rem;
482 }
511 }
483
512
484 /* Changelist */
513 /* Changelist */
485
514
486 #changelist {
515 #changelist {
487 display: flex;
516 align-items: stretch;
488 flex-direction: column;
517 flex-direction: column;
489 }
518 }
490
519
491 #changelist #toolbar {
520 #toolbar {
492 order: 1;
493 padding: 10px;
521 padding: 10px;
494 }
522 }
495
523
496 #changelist .xfull {
497 order: 2;
498 }
499
500 #changelist-form {
501 order: 3;
502 }
503
504 #changelist-filter {
524 #changelist-filter {
505 order: 4;
525 margin-left: 0;
506 }
526 }
507
527
508 #changelist .actions label {
528 #changelist .actions label {
@@ -518,11 +538,6 input[type="submit"], button {
518 flex: 1 0 100%;
538 flex: 1 0 100%;
519 }
539 }
520
540
521 .change-list .filtered .results, .change-list .filtered .paginator,
522 .filtered #toolbar, .filtered .actions, .filtered div.xfull {
523 margin-right: 0;
524 }
525
526 #changelist-filter {
541 #changelist-filter {
527 position: static;
542 position: static;
528 width: auto;
543 width: auto;
@@ -618,7 +633,7 input[type="submit"], button {
618
633
619 .aligned p.file-upload {
634 .aligned p.file-upload {
620 margin-left: 0;
635 margin-left: 0;
621 font-size: 13px;
636 font-size: 0.8125rem;
622 }
637 }
623
638
624 span.clearable-file-input {
639 span.clearable-file-input {
@@ -626,7 +641,7 input[type="submit"], button {
626 }
641 }
627
642
628 span.clearable-file-input label {
643 span.clearable-file-input label {
629 font-size: 13px;
644 font-size: 0.8125rem;
630 padding-bottom: 0;
645 padding-bottom: 0;
631 }
646 }
632
647
@@ -646,12 +661,13 input[type="submit"], button {
646 padding-left: 0;
661 padding-left: 0;
647 }
662 }
648
663
649 form .aligned ul.radiolist {
664 form .aligned div.radiolist {
665 margin-top: 5px;
650 margin-right: 15px;
666 margin-right: 15px;
651 margin-bottom: -3px;
667 margin-bottom: -3px;
652 }
668 }
653
669
654 form .aligned ul.radiolist li + li {
670 form .aligned div.radiolist:not(.inline) div + div {
655 margin-top: 5px;
671 margin-top: 5px;
656 }
672 }
657
673
@@ -721,14 +737,22 input[type="submit"], button {
721 background-position: 0 0;
737 background-position: 0 0;
722 }
738 }
723
739
740 .active.selector-remove:focus, .active.selector-remove:hover {
741 background-position: 0 -20px;
742 }
743
724 .selector-add {
744 .selector-add {
725 background-position: 0 -40px;
745 background-position: 0 -40px;
726 }
746 }
727
747
748 .active.selector-add:focus, .active.selector-add:hover {
749 background-position: 0 -60px;
750 }
751
728 /* Inlines */
752 /* Inlines */
729
753
730 .inline-group[data-inline-type="stacked"] .inline-related {
754 .inline-group[data-inline-type="stacked"] .inline-related {
731 border: 2px solid #eee;
755 border: 1px solid var(--hairline-color);
732 border-radius: 4px;
756 border-radius: 4px;
733 margin-top: 15px;
757 margin-top: 15px;
734 overflow: auto;
758 overflow: auto;
@@ -738,18 +762,19 input[type="submit"], button {
738 box-sizing: border-box;
762 box-sizing: border-box;
739 }
763 }
740
764
741 .inline-group[data-inline-type="stacked"] .inline-related + .inline-related {
742 margin-top: 30px;
743 }
744
745 .inline-group[data-inline-type="stacked"] .inline-related .module {
765 .inline-group[data-inline-type="stacked"] .inline-related .module {
746 padding: 0 10px;
766 padding: 0 10px;
747 }
767 }
748
768
749 .inline-group[data-inline-type="stacked"] .inline-related .module .form-row:last-child {
769 .inline-group[data-inline-type="stacked"] .inline-related .module .form-row {
770 border-top: 1px solid var(--hairline-color);
750 border-bottom: none;
771 border-bottom: none;
751 }
772 }
752
773
774 .inline-group[data-inline-type="stacked"] .inline-related .module .form-row:first-child {
775 border-top: none;
776 }
777
753 .inline-group[data-inline-type="stacked"] .inline-related h3 {
778 .inline-group[data-inline-type="stacked"] .inline-related h3 {
754 padding: 10px;
779 padding: 10px;
755 border-top-width: 0;
780 border-top-width: 0;
@@ -779,7 +804,7 input[type="submit"], button {
779
804
780 .inline-group[data-inline-type="stacked"] div.add-row {
805 .inline-group[data-inline-type="stacked"] div.add-row {
781 margin-top: 15px;
806 margin-top: 15px;
782 border: 1px solid #eee;
807 border: 1px solid var(--hairline-color);
783 border-radius: 4px;
808 border-radius: 4px;
784 }
809 }
785
810
@@ -798,7 +823,7 input[type="submit"], button {
798 /* Submit row */
823 /* Submit row */
799
824
800 .submit-row {
825 .submit-row {
801 padding: 10px 10px 0;
826 padding: 10px 10px 5px;
802 margin: 0 0 15px;
827 margin: 0 0 15px;
803 display: flex;
828 display: flex;
804 flex-direction: column;
829 flex-direction: column;
@@ -873,9 +898,7 input[type="submit"], button {
873 }
898 }
874
899
875 .login .form-row label {
900 .login .form-row label {
876 display: block;
877 margin: 0 0 5px;
901 margin: 0 0 5px;
878 padding: 0;
879 line-height: 1.2;
902 line-height: 1.2;
880 }
903 }
881
904
@@ -883,7 +906,7 input[type="submit"], button {
883 padding: 15px 0 0;
906 padding: 15px 0 0;
884 }
907 }
885
908
886 .login br, .login .submit-row label {
909 .login br {
887 display: none;
910 display: none;
888 }
911 }
889
912
@@ -895,7 +918,7 input[type="submit"], button {
895 .errornote {
918 .errornote {
896 margin: 0 0 20px;
919 margin: 0 0 20px;
897 padding: 8px 12px;
920 padding: 8px 12px;
898 font-size: 13px;
921 font-size: 0.8125rem;
899 }
922 }
900
923
901 /* Calendar and clock */
924 /* Calendar and clock */
@@ -942,7 +965,7 input[type="submit"], button {
942
965
943 .calendar-shortcuts {
966 .calendar-shortcuts {
944 padding: 10px 0;
967 padding: 10px 0;
945 font-size: 12px;
968 font-size: 0.75rem;
946 line-height: 12px;
969 line-height: 12px;
947 }
970 }
948
971
@@ -951,7 +974,7 input[type="submit"], button {
951 }
974 }
952
975
953 .timelist a {
976 .timelist a {
954 background: #fff;
977 background: var(--body-bg);
955 padding: 4px;
978 padding: 4px;
956 }
979 }
957
980
@@ -975,7 +998,7 input[type="submit"], button {
975 /* History */
998 /* History */
976
999
977 table#change-history tbody th, table#change-history tbody td {
1000 table#change-history tbody th, table#change-history tbody td {
978 font-size: 13px;
1001 font-size: 0.8125rem;
979 word-break: break-word;
1002 word-break: break-word;
980 }
1003 }
981
1004
@@ -986,7 +1009,7 input[type="submit"], button {
986 /* Docs */
1009 /* Docs */
987
1010
988 table.model tbody th, table.model tbody td {
1011 table.model tbody th, table.model tbody td {
989 font-size: 13px;
1012 font-size: 0.8125rem;
990 word-break: break-word;
1013 word-break: break-word;
991 }
1014 }
992 }
1015 }
@@ -23,9 +23,9
23 [dir="rtl"] .change-list .filtered .paginator,
23 [dir="rtl"] .change-list .filtered .paginator,
24 [dir="rtl"] .filtered #toolbar,
24 [dir="rtl"] .filtered #toolbar,
25 [dir="rtl"] .filtered div.xfull,
25 [dir="rtl"] .filtered div.xfull,
26 [dir="rtl"] .filtered .actions {
26 [dir="rtl"] .filtered .actions,
27 margin-right: 0;
27 [dir="rtl"] #changelist-filter {
28 margin-left: 230px;
28 margin-left: 0;
29 }
29 }
30
30
31 [dir="rtl"] .inline-group ul.tools a.add,
31 [dir="rtl"] .inline-group ul.tools a.add,
@@ -63,15 +63,6
63 /* MOBILE */
63 /* MOBILE */
64
64
65 @media (max-width: 767px) {
65 @media (max-width: 767px) {
66 [dir="rtl"] .change-list .filtered .results,
67 [dir="rtl"] .change-list .filtered .paginator,
68 [dir="rtl"] .filtered #toolbar,
69 [dir="rtl"] .filtered div.xfull,
70 [dir="rtl"] .filtered .actions {
71 margin-left: 0;
72 }
73
74 [dir="rtl"] .aligned .add-another,
75 [dir="rtl"] .aligned .related-lookup,
66 [dir="rtl"] .aligned .related-lookup,
76 [dir="rtl"] .aligned .datetimeshortcuts {
67 [dir="rtl"] .aligned .datetimeshortcuts {
77 margin-left: 0;
68 margin-left: 0;
@@ -81,4 +72,9
81 [dir="rtl"] .aligned ul {
72 [dir="rtl"] .aligned ul {
82 margin-right: 0;
73 margin-right: 0;
83 }
74 }
75
76 [dir="rtl"] #changelist-filter {
77 margin-left: 0;
78 margin-right: 0;
79 }
84 }
80 }
@@ -1,25 +1,3
1 body {
2 direction: rtl;
3 }
4
5 /* LOGIN */
6
7 .login .form-row {
8 float: right;
9 }
10
11 .login .form-row label {
12 float: right;
13 padding-left: 0.5em;
14 padding-right: 0;
15 text-align: left;
16 }
17
18 .login .submit-row {
19 clear: both;
20 padding: 1em 9.4em 0 0;
21 }
22
23 /* GLOBAL */
1 /* GLOBAL */
24
2
25 th {
3 th {
@@ -109,31 +87,21 thead th.sorted .text {
109 }
87 }
110
88
111 #changelist-filter {
89 #changelist-filter {
112 right: auto;
113 left: 0;
114 border-left: none;
90 border-left: none;
115 border-right: none;
91 border-right: none;
116 }
92 margin-left: 0;
117
93 margin-right: 30px;
118 .change-list .filtered .results, .change-list .filtered .paginator, .filtered #toolbar, .filtered div.xfull {
119 margin-right: 0;
120 margin-left: 280px;
121 }
94 }
122
95
123 #changelist-filter li.selected {
96 #changelist-filter li.selected {
124 border-left: none;
97 border-left: none;
125 padding-left: 10px;
98 padding-left: 10px;
126 margin-left: 0;
99 margin-left: 0;
127 border-right: 5px solid #eaeaea;
100 border-right: 5px solid var(--hairline-color);
128 padding-right: 10px;
101 padding-right: 10px;
129 margin-right: -15px;
102 margin-right: -15px;
130 }
103 }
131
104
132 .filtered .actions {
133 margin-left: 280px;
134 margin-right: 0;
135 }
136
137 #changelist table tbody td:first-child, #changelist table tbody th:first-child {
105 #changelist table tbody td:first-child, #changelist table tbody th:first-child {
138 border-right: none;
106 border-right: none;
139 border-left: none;
107 border-left: none;
@@ -207,12 +175,24 fieldset .fieldBox {
207 top: 0;
175 top: 0;
208 left: auto;
176 left: auto;
209 right: 10px;
177 right: 10px;
178 background: url(../img/calendar-icons.svg) 0 -30px no-repeat;
179 }
180
181 .calendarbox .calendarnav-previous:focus,
182 .calendarbox .calendarnav-previous:hover {
183 background-position: 0 -45px;
210 }
184 }
211
185
212 .calendarnav-next {
186 .calendarnav-next {
213 top: 0;
187 top: 0;
214 right: auto;
188 right: auto;
215 left: 10px;
189 left: 10px;
190 background: url(../img/calendar-icons.svg) 0 0 no-repeat;
191 }
192
193 .calendarbox .calendarnav-next:focus,
194 .calendarbox .calendarnav-next:hover {
195 background-position: 0 -15px;
216 }
196 }
217
197
218 .calendar caption, .calendarbox h2 {
198 .calendar caption, .calendarbox h2 {
@@ -257,13 +237,3 form .form-row p.datetime {
257 margin-left: inherit;
237 margin-left: inherit;
258 margin-right: 2px;
238 margin-right: 2px;
259 }
239 }
260
261 /* IE7 specific bug fixes */
262
263 div.colM {
264 position: relative;
265 }
266
267 .submit-row input {
268 float: left;
269 }
@@ -1,6 +1,6
1 The MIT License (MIT)
1 The MIT License (MIT)
2
2
3 Copyright (c) 2012-2015 Kevin Brown, Igor Vaynberg, and Select2 contributors
3 Copyright (c) 2012-2017 Kevin Brown, Igor Vaynberg, and Select2 contributors
4
4
5 Permission is hereby granted, free of charge, to any person obtaining a copy
5 Permission is hereby granted, free of charge, to any person obtaining a copy
6 of this software and associated documentation files (the "Software"), to deal
6 of this software and associated documentation files (the "Software"), to deal
@@ -118,12 +118,14
118 .select2-hidden-accessible {
118 .select2-hidden-accessible {
119 border: 0 !important;
119 border: 0 !important;
120 clip: rect(0 0 0 0) !important;
120 clip: rect(0 0 0 0) !important;
121 -webkit-clip-path: inset(50%) !important;
122 clip-path: inset(50%) !important;
121 height: 1px !important;
123 height: 1px !important;
122 margin: -1px !important;
123 overflow: hidden !important;
124 overflow: hidden !important;
124 padding: 0 !important;
125 padding: 0 !important;
125 position: absolute !important;
126 position: absolute !important;
126 width: 1px !important; }
127 width: 1px !important;
128 white-space: nowrap !important; }
127
129
128 .select2-container--default .select2-selection--single {
130 .select2-container--default .select2-selection--single {
129 background-color: #fff;
131 background-color: #fff;
@@ -186,16 +188,13
186 width: 100%; }
188 width: 100%; }
187 .select2-container--default .select2-selection--multiple .select2-selection__rendered li {
189 .select2-container--default .select2-selection--multiple .select2-selection__rendered li {
188 list-style: none; }
190 list-style: none; }
189 .select2-container--default .select2-selection--multiple .select2-selection__placeholder {
190 color: #999;
191 margin-top: 5px;
192 float: left; }
193 .select2-container--default .select2-selection--multiple .select2-selection__clear {
191 .select2-container--default .select2-selection--multiple .select2-selection__clear {
194 cursor: pointer;
192 cursor: pointer;
195 float: right;
193 float: right;
196 font-weight: bold;
194 font-weight: bold;
197 margin-top: 5px;
195 margin-top: 5px;
198 margin-right: 10px; }
196 margin-right: 10px;
197 padding: 1px; }
199 .select2-container--default .select2-selection--multiple .select2-selection__choice {
198 .select2-container--default .select2-selection--multiple .select2-selection__choice {
200 background-color: #e4e4e4;
199 background-color: #e4e4e4;
201 border: 1px solid #aaa;
200 border: 1px solid #aaa;
@@ -214,7 +213,7
214 .select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover {
213 .select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover {
215 color: #333; }
214 color: #333; }
216
215
217 .select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice, .select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__placeholder, .select2-container--default[dir="rtl"] .select2-selection--multiple .select2-search--inline {
216 .select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice, .select2-container--default[dir="rtl"] .select2-selection--multiple .select2-search--inline {
218 float: right; }
217 float: right; }
219
218
220 .select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice {
219 .select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice {
@@ -420,9 +419,7
420 color: #555; }
419 color: #555; }
421
420
422 .select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice {
421 .select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice {
423 float: right; }
422 float: right;
424
425 .select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice {
426 margin-left: 5px;
423 margin-left: 5px;
427 margin-right: auto; }
424 margin-right: auto; }
428
425
@@ -1,1 +1,1
1 .select2-container{box-sizing:border-box;display:inline-block;margin:0;position:relative;vertical-align:middle}.select2-container .select2-selection--single{box-sizing:border-box;cursor:pointer;display:block;height:28px;user-select:none;-webkit-user-select:none}.select2-container .select2-selection--single .select2-selection__rendered{display:block;padding-left:8px;padding-right:20px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.select2-container .select2-selection--single .select2-selection__clear{position:relative}.select2-container[dir="rtl"] .select2-selection--single .select2-selection__rendered{padding-right:8px;padding-left:20px}.select2-container .select2-selection--multiple{box-sizing:border-box;cursor:pointer;display:block;min-height:32px;user-select:none;-webkit-user-select:none}.select2-container .select2-selection--multiple .select2-selection__rendered{display:inline-block;overflow:hidden;padding-left:8px;text-overflow:ellipsis;white-space:nowrap}.select2-container .select2-search--inline{float:left}.select2-container .select2-search--inline .select2-search__field{box-sizing:border-box;border:none;font-size:100%;margin-top:5px;padding:0}.select2-container .select2-search--inline .select2-search__field::-webkit-search-cancel-button{-webkit-appearance:none}.select2-dropdown{background-color:white;border:1px solid #aaa;border-radius:4px;box-sizing:border-box;display:block;position:absolute;left:-100000px;width:100%;z-index:1051}.select2-results{display:block}.select2-results__options{list-style:none;margin:0;padding:0}.select2-results__option{padding:6px;user-select:none;-webkit-user-select:none}.select2-results__option[aria-selected]{cursor:pointer}.select2-container--open .select2-dropdown{left:0}.select2-container--open .select2-dropdown--above{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--open .select2-dropdown--below{border-top:none;border-top-left-radius:0;border-top-right-radius:0}.select2-search--dropdown{display:block;padding:4px}.select2-search--dropdown .select2-search__field{padding:4px;width:100%;box-sizing:border-box}.select2-search--dropdown .select2-search__field::-webkit-search-cancel-button{-webkit-appearance:none}.select2-search--dropdown.select2-search--hide{display:none}.select2-close-mask{border:0;margin:0;padding:0;display:block;position:fixed;left:0;top:0;min-height:100%;min-width:100%;height:auto;width:auto;opacity:0;z-index:99;background-color:#fff;filter:alpha(opacity=0)}.select2-hidden-accessible{border:0 !important;clip:rect(0 0 0 0) !important;height:1px !important;margin:-1px !important;overflow:hidden !important;padding:0 !important;position:absolute !important;width:1px !important}.select2-container--default .select2-selection--single{background-color:#fff;border:1px solid #aaa;border-radius:4px}.select2-container--default .select2-selection--single .select2-selection__rendered{color:#444;line-height:28px}.select2-container--default .select2-selection--single .select2-selection__clear{cursor:pointer;float:right;font-weight:bold}.select2-container--default .select2-selection--single .select2-selection__placeholder{color:#999}.select2-container--default .select2-selection--single .select2-selection__arrow{height:26px;position:absolute;top:1px;right:1px;width:20px}.select2-container--default .select2-selection--single .select2-selection__arrow b{border-color:#888 transparent transparent transparent;border-style:solid;border-width:5px 4px 0 4px;height:0;left:50%;margin-left:-4px;margin-top:-2px;position:absolute;top:50%;width:0}.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__clear{float:left}.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__arrow{left:1px;right:auto}.select2-container--default.select2-container--disabled .select2-selection--single{background-color:#eee;cursor:default}.select2-container--default.select2-container--disabled .select2-selection--single .select2-selection__clear{display:none}.select2-container--default.select2-container--open .select2-selection--single .select2-selection__arrow b{border-color:transparent transparent #888 transparent;border-width:0 4px 5px 4px}.select2-container--default .select2-selection--multiple{background-color:white;border:1px solid #aaa;border-radius:4px;cursor:text}.select2-container--default .select2-selection--multiple .select2-selection__rendered{box-sizing:border-box;list-style:none;margin:0;padding:0 5px;width:100%}.select2-container--default .select2-selection--multiple .select2-selection__rendered li{list-style:none}.select2-container--default .select2-selection--multiple .select2-selection__placeholder{color:#999;margin-top:5px;float:left}.select2-container--default .select2-selection--multiple .select2-selection__clear{cursor:pointer;float:right;font-weight:bold;margin-top:5px;margin-right:10px}.select2-container--default .select2-selection--multiple .select2-selection__choice{background-color:#e4e4e4;border:1px solid #aaa;border-radius:4px;cursor:default;float:left;margin-right:5px;margin-top:5px;padding:0 5px}.select2-container--default .select2-selection--multiple .select2-selection__choice__remove{color:#999;cursor:pointer;display:inline-block;font-weight:bold;margin-right:2px}.select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover{color:#333}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice,.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__placeholder,.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-search--inline{float:right}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice{margin-left:5px;margin-right:auto}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove{margin-left:2px;margin-right:auto}.select2-container--default.select2-container--focus .select2-selection--multiple{border:solid black 1px;outline:0}.select2-container--default.select2-container--disabled .select2-selection--multiple{background-color:#eee;cursor:default}.select2-container--default.select2-container--disabled .select2-selection__choice__remove{display:none}.select2-container--default.select2-container--open.select2-container--above .select2-selection--single,.select2-container--default.select2-container--open.select2-container--above .select2-selection--multiple{border-top-left-radius:0;border-top-right-radius:0}.select2-container--default.select2-container--open.select2-container--below .select2-selection--single,.select2-container--default.select2-container--open.select2-container--below .select2-selection--multiple{border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--default .select2-search--dropdown .select2-search__field{border:1px solid #aaa}.select2-container--default .select2-search--inline .select2-search__field{background:transparent;border:none;outline:0;box-shadow:none;-webkit-appearance:textfield}.select2-container--default .select2-results>.select2-results__options{max-height:200px;overflow-y:auto}.select2-container--default .select2-results__option[role=group]{padding:0}.select2-container--default .select2-results__option[aria-disabled=true]{color:#999}.select2-container--default .select2-results__option[aria-selected=true]{background-color:#ddd}.select2-container--default .select2-results__option .select2-results__option{padding-left:1em}.select2-container--default .select2-results__option .select2-results__option .select2-results__group{padding-left:0}.select2-container--default .select2-results__option .select2-results__option .select2-results__option{margin-left:-1em;padding-left:2em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-2em;padding-left:3em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-3em;padding-left:4em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-4em;padding-left:5em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-5em;padding-left:6em}.select2-container--default .select2-results__option--highlighted[aria-selected]{background-color:#5897fb;color:white}.select2-container--default .select2-results__group{cursor:default;display:block;padding:6px}.select2-container--classic .select2-selection--single{background-color:#f7f7f7;border:1px solid #aaa;border-radius:4px;outline:0;background-image:-webkit-linear-gradient(top, #fff 50%, #eee 100%);background-image:-o-linear-gradient(top, #fff 50%, #eee 100%);background-image:linear-gradient(to bottom, #fff 50%, #eee 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0)}.select2-container--classic .select2-selection--single:focus{border:1px solid #5897fb}.select2-container--classic .select2-selection--single .select2-selection__rendered{color:#444;line-height:28px}.select2-container--classic .select2-selection--single .select2-selection__clear{cursor:pointer;float:right;font-weight:bold;margin-right:10px}.select2-container--classic .select2-selection--single .select2-selection__placeholder{color:#999}.select2-container--classic .select2-selection--single .select2-selection__arrow{background-color:#ddd;border:none;border-left:1px solid #aaa;border-top-right-radius:4px;border-bottom-right-radius:4px;height:26px;position:absolute;top:1px;right:1px;width:20px;background-image:-webkit-linear-gradient(top, #eee 50%, #ccc 100%);background-image:-o-linear-gradient(top, #eee 50%, #ccc 100%);background-image:linear-gradient(to bottom, #eee 50%, #ccc 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFCCCCCC', GradientType=0)}.select2-container--classic .select2-selection--single .select2-selection__arrow b{border-color:#888 transparent transparent transparent;border-style:solid;border-width:5px 4px 0 4px;height:0;left:50%;margin-left:-4px;margin-top:-2px;position:absolute;top:50%;width:0}.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__clear{float:left}.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__arrow{border:none;border-right:1px solid #aaa;border-radius:0;border-top-left-radius:4px;border-bottom-left-radius:4px;left:1px;right:auto}.select2-container--classic.select2-container--open .select2-selection--single{border:1px solid #5897fb}.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow{background:transparent;border:none}.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow b{border-color:transparent transparent #888 transparent;border-width:0 4px 5px 4px}.select2-container--classic.select2-container--open.select2-container--above .select2-selection--single{border-top:none;border-top-left-radius:0;border-top-right-radius:0;background-image:-webkit-linear-gradient(top, #fff 0%, #eee 50%);background-image:-o-linear-gradient(top, #fff 0%, #eee 50%);background-image:linear-gradient(to bottom, #fff 0%, #eee 50%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0)}.select2-container--classic.select2-container--open.select2-container--below .select2-selection--single{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0;background-image:-webkit-linear-gradient(top, #eee 50%, #fff 100%);background-image:-o-linear-gradient(top, #eee 50%, #fff 100%);background-image:linear-gradient(to bottom, #eee 50%, #fff 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFFFFFFF', GradientType=0)}.select2-container--classic .select2-selection--multiple{background-color:white;border:1px solid #aaa;border-radius:4px;cursor:text;outline:0}.select2-container--classic .select2-selection--multiple:focus{border:1px solid #5897fb}.select2-container--classic .select2-selection--multiple .select2-selection__rendered{list-style:none;margin:0;padding:0 5px}.select2-container--classic .select2-selection--multiple .select2-selection__clear{display:none}.select2-container--classic .select2-selection--multiple .select2-selection__choice{background-color:#e4e4e4;border:1px solid #aaa;border-radius:4px;cursor:default;float:left;margin-right:5px;margin-top:5px;padding:0 5px}.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove{color:#888;cursor:pointer;display:inline-block;font-weight:bold;margin-right:2px}.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove:hover{color:#555}.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice{float:right}.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice{margin-left:5px;margin-right:auto}.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove{margin-left:2px;margin-right:auto}.select2-container--classic.select2-container--open .select2-selection--multiple{border:1px solid #5897fb}.select2-container--classic.select2-container--open.select2-container--above .select2-selection--multiple{border-top:none;border-top-left-radius:0;border-top-right-radius:0}.select2-container--classic.select2-container--open.select2-container--below .select2-selection--multiple{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--classic .select2-search--dropdown .select2-search__field{border:1px solid #aaa;outline:0}.select2-container--classic .select2-search--inline .select2-search__field{outline:0;box-shadow:none}.select2-container--classic .select2-dropdown{background-color:#fff;border:1px solid transparent}.select2-container--classic .select2-dropdown--above{border-bottom:none}.select2-container--classic .select2-dropdown--below{border-top:none}.select2-container--classic .select2-results>.select2-results__options{max-height:200px;overflow-y:auto}.select2-container--classic .select2-results__option[role=group]{padding:0}.select2-container--classic .select2-results__option[aria-disabled=true]{color:grey}.select2-container--classic .select2-results__option--highlighted[aria-selected]{background-color:#3875d7;color:#fff}.select2-container--classic .select2-results__group{cursor:default;display:block;padding:6px}.select2-container--classic.select2-container--open .select2-dropdown{border-color:#5897fb}
1 .select2-container{box-sizing:border-box;display:inline-block;margin:0;position:relative;vertical-align:middle}.select2-container .select2-selection--single{box-sizing:border-box;cursor:pointer;display:block;height:28px;user-select:none;-webkit-user-select:none}.select2-container .select2-selection--single .select2-selection__rendered{display:block;padding-left:8px;padding-right:20px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.select2-container .select2-selection--single .select2-selection__clear{position:relative}.select2-container[dir="rtl"] .select2-selection--single .select2-selection__rendered{padding-right:8px;padding-left:20px}.select2-container .select2-selection--multiple{box-sizing:border-box;cursor:pointer;display:block;min-height:32px;user-select:none;-webkit-user-select:none}.select2-container .select2-selection--multiple .select2-selection__rendered{display:inline-block;overflow:hidden;padding-left:8px;text-overflow:ellipsis;white-space:nowrap}.select2-container .select2-search--inline{float:left}.select2-container .select2-search--inline .select2-search__field{box-sizing:border-box;border:none;font-size:100%;margin-top:5px;padding:0}.select2-container .select2-search--inline .select2-search__field::-webkit-search-cancel-button{-webkit-appearance:none}.select2-dropdown{background-color:white;border:1px solid #aaa;border-radius:4px;box-sizing:border-box;display:block;position:absolute;left:-100000px;width:100%;z-index:1051}.select2-results{display:block}.select2-results__options{list-style:none;margin:0;padding:0}.select2-results__option{padding:6px;user-select:none;-webkit-user-select:none}.select2-results__option[aria-selected]{cursor:pointer}.select2-container--open .select2-dropdown{left:0}.select2-container--open .select2-dropdown--above{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--open .select2-dropdown--below{border-top:none;border-top-left-radius:0;border-top-right-radius:0}.select2-search--dropdown{display:block;padding:4px}.select2-search--dropdown .select2-search__field{padding:4px;width:100%;box-sizing:border-box}.select2-search--dropdown .select2-search__field::-webkit-search-cancel-button{-webkit-appearance:none}.select2-search--dropdown.select2-search--hide{display:none}.select2-close-mask{border:0;margin:0;padding:0;display:block;position:fixed;left:0;top:0;min-height:100%;min-width:100%;height:auto;width:auto;opacity:0;z-index:99;background-color:#fff;filter:alpha(opacity=0)}.select2-hidden-accessible{border:0 !important;clip:rect(0 0 0 0) !important;-webkit-clip-path:inset(50%) !important;clip-path:inset(50%) !important;height:1px !important;overflow:hidden !important;padding:0 !important;position:absolute !important;width:1px !important;white-space:nowrap !important}.select2-container--default .select2-selection--single{background-color:#fff;border:1px solid #aaa;border-radius:4px}.select2-container--default .select2-selection--single .select2-selection__rendered{color:#444;line-height:28px}.select2-container--default .select2-selection--single .select2-selection__clear{cursor:pointer;float:right;font-weight:bold}.select2-container--default .select2-selection--single .select2-selection__placeholder{color:#999}.select2-container--default .select2-selection--single .select2-selection__arrow{height:26px;position:absolute;top:1px;right:1px;width:20px}.select2-container--default .select2-selection--single .select2-selection__arrow b{border-color:#888 transparent transparent transparent;border-style:solid;border-width:5px 4px 0 4px;height:0;left:50%;margin-left:-4px;margin-top:-2px;position:absolute;top:50%;width:0}.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__clear{float:left}.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__arrow{left:1px;right:auto}.select2-container--default.select2-container--disabled .select2-selection--single{background-color:#eee;cursor:default}.select2-container--default.select2-container--disabled .select2-selection--single .select2-selection__clear{display:none}.select2-container--default.select2-container--open .select2-selection--single .select2-selection__arrow b{border-color:transparent transparent #888 transparent;border-width:0 4px 5px 4px}.select2-container--default .select2-selection--multiple{background-color:white;border:1px solid #aaa;border-radius:4px;cursor:text}.select2-container--default .select2-selection--multiple .select2-selection__rendered{box-sizing:border-box;list-style:none;margin:0;padding:0 5px;width:100%}.select2-container--default .select2-selection--multiple .select2-selection__rendered li{list-style:none}.select2-container--default .select2-selection--multiple .select2-selection__clear{cursor:pointer;float:right;font-weight:bold;margin-top:5px;margin-right:10px;padding:1px}.select2-container--default .select2-selection--multiple .select2-selection__choice{background-color:#e4e4e4;border:1px solid #aaa;border-radius:4px;cursor:default;float:left;margin-right:5px;margin-top:5px;padding:0 5px}.select2-container--default .select2-selection--multiple .select2-selection__choice__remove{color:#999;cursor:pointer;display:inline-block;font-weight:bold;margin-right:2px}.select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover{color:#333}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice,.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-search--inline{float:right}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice{margin-left:5px;margin-right:auto}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove{margin-left:2px;margin-right:auto}.select2-container--default.select2-container--focus .select2-selection--multiple{border:solid black 1px;outline:0}.select2-container--default.select2-container--disabled .select2-selection--multiple{background-color:#eee;cursor:default}.select2-container--default.select2-container--disabled .select2-selection__choice__remove{display:none}.select2-container--default.select2-container--open.select2-container--above .select2-selection--single,.select2-container--default.select2-container--open.select2-container--above .select2-selection--multiple{border-top-left-radius:0;border-top-right-radius:0}.select2-container--default.select2-container--open.select2-container--below .select2-selection--single,.select2-container--default.select2-container--open.select2-container--below .select2-selection--multiple{border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--default .select2-search--dropdown .select2-search__field{border:1px solid #aaa}.select2-container--default .select2-search--inline .select2-search__field{background:transparent;border:none;outline:0;box-shadow:none;-webkit-appearance:textfield}.select2-container--default .select2-results>.select2-results__options{max-height:200px;overflow-y:auto}.select2-container--default .select2-results__option[role=group]{padding:0}.select2-container--default .select2-results__option[aria-disabled=true]{color:#999}.select2-container--default .select2-results__option[aria-selected=true]{background-color:#ddd}.select2-container--default .select2-results__option .select2-results__option{padding-left:1em}.select2-container--default .select2-results__option .select2-results__option .select2-results__group{padding-left:0}.select2-container--default .select2-results__option .select2-results__option .select2-results__option{margin-left:-1em;padding-left:2em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-2em;padding-left:3em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-3em;padding-left:4em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-4em;padding-left:5em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-5em;padding-left:6em}.select2-container--default .select2-results__option--highlighted[aria-selected]{background-color:#5897fb;color:white}.select2-container--default .select2-results__group{cursor:default;display:block;padding:6px}.select2-container--classic .select2-selection--single{background-color:#f7f7f7;border:1px solid #aaa;border-radius:4px;outline:0;background-image:-webkit-linear-gradient(top, #fff 50%, #eee 100%);background-image:-o-linear-gradient(top, #fff 50%, #eee 100%);background-image:linear-gradient(to bottom, #fff 50%, #eee 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0)}.select2-container--classic .select2-selection--single:focus{border:1px solid #5897fb}.select2-container--classic .select2-selection--single .select2-selection__rendered{color:#444;line-height:28px}.select2-container--classic .select2-selection--single .select2-selection__clear{cursor:pointer;float:right;font-weight:bold;margin-right:10px}.select2-container--classic .select2-selection--single .select2-selection__placeholder{color:#999}.select2-container--classic .select2-selection--single .select2-selection__arrow{background-color:#ddd;border:none;border-left:1px solid #aaa;border-top-right-radius:4px;border-bottom-right-radius:4px;height:26px;position:absolute;top:1px;right:1px;width:20px;background-image:-webkit-linear-gradient(top, #eee 50%, #ccc 100%);background-image:-o-linear-gradient(top, #eee 50%, #ccc 100%);background-image:linear-gradient(to bottom, #eee 50%, #ccc 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFCCCCCC', GradientType=0)}.select2-container--classic .select2-selection--single .select2-selection__arrow b{border-color:#888 transparent transparent transparent;border-style:solid;border-width:5px 4px 0 4px;height:0;left:50%;margin-left:-4px;margin-top:-2px;position:absolute;top:50%;width:0}.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__clear{float:left}.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__arrow{border:none;border-right:1px solid #aaa;border-radius:0;border-top-left-radius:4px;border-bottom-left-radius:4px;left:1px;right:auto}.select2-container--classic.select2-container--open .select2-selection--single{border:1px solid #5897fb}.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow{background:transparent;border:none}.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow b{border-color:transparent transparent #888 transparent;border-width:0 4px 5px 4px}.select2-container--classic.select2-container--open.select2-container--above .select2-selection--single{border-top:none;border-top-left-radius:0;border-top-right-radius:0;background-image:-webkit-linear-gradient(top, #fff 0%, #eee 50%);background-image:-o-linear-gradient(top, #fff 0%, #eee 50%);background-image:linear-gradient(to bottom, #fff 0%, #eee 50%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0)}.select2-container--classic.select2-container--open.select2-container--below .select2-selection--single{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0;background-image:-webkit-linear-gradient(top, #eee 50%, #fff 100%);background-image:-o-linear-gradient(top, #eee 50%, #fff 100%);background-image:linear-gradient(to bottom, #eee 50%, #fff 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFFFFFFF', GradientType=0)}.select2-container--classic .select2-selection--multiple{background-color:white;border:1px solid #aaa;border-radius:4px;cursor:text;outline:0}.select2-container--classic .select2-selection--multiple:focus{border:1px solid #5897fb}.select2-container--classic .select2-selection--multiple .select2-selection__rendered{list-style:none;margin:0;padding:0 5px}.select2-container--classic .select2-selection--multiple .select2-selection__clear{display:none}.select2-container--classic .select2-selection--multiple .select2-selection__choice{background-color:#e4e4e4;border:1px solid #aaa;border-radius:4px;cursor:default;float:left;margin-right:5px;margin-top:5px;padding:0 5px}.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove{color:#888;cursor:pointer;display:inline-block;font-weight:bold;margin-right:2px}.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove:hover{color:#555}.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice{float:right;margin-left:5px;margin-right:auto}.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove{margin-left:2px;margin-right:auto}.select2-container--classic.select2-container--open .select2-selection--multiple{border:1px solid #5897fb}.select2-container--classic.select2-container--open.select2-container--above .select2-selection--multiple{border-top:none;border-top-left-radius:0;border-top-right-radius:0}.select2-container--classic.select2-container--open.select2-container--below .select2-selection--multiple{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--classic .select2-search--dropdown .select2-search__field{border:1px solid #aaa;outline:0}.select2-container--classic .select2-search--inline .select2-search__field{outline:0;box-shadow:none}.select2-container--classic .select2-dropdown{background-color:#fff;border:1px solid transparent}.select2-container--classic .select2-dropdown--above{border-bottom:none}.select2-container--classic .select2-dropdown--below{border-top:none}.select2-container--classic .select2-results>.select2-results__options{max-height:200px;overflow-y:auto}.select2-container--classic .select2-results__option[role=group]{padding:0}.select2-container--classic .select2-results__option[aria-disabled=true]{color:grey}.select2-container--classic .select2-results__option--highlighted[aria-selected]{background-color:#3875d7;color:#fff}.select2-container--classic .select2-results__group{cursor:default;display:block;padding:6px}.select2-container--classic.select2-container--open .select2-dropdown{border-color:#5897fb}
@@ -3,18 +3,21
3 .selector {
3 .selector {
4 width: 800px;
4 width: 800px;
5 float: left;
5 float: left;
6 display: flex;
6 }
7 }
7
8
8 .selector select {
9 .selector select {
9 width: 380px;
10 width: 380px;
10 height: 17.2em;
11 height: 17.2em;
12 flex: 1 0 auto;
11 }
13 }
12
14
13 .selector-available, .selector-chosen {
15 .selector-available, .selector-chosen {
14 float: left;
15 width: 380px;
16 width: 380px;
16 text-align: center;
17 text-align: center;
17 margin-bottom: 5px;
18 margin-bottom: 5px;
19 display: flex;
20 flex-direction: column;
18 }
21 }
19
22
20 .selector-chosen select {
23 .selector-chosen select {
@@ -22,27 +25,26
22 }
25 }
23
26
24 .selector-available h2, .selector-chosen h2 {
27 .selector-available h2, .selector-chosen h2 {
25 border: 1px solid #ccc;
28 border: 1px solid var(--border-color);
26 border-radius: 4px 4px 0 0;
29 border-radius: 4px 4px 0 0;
27 }
30 }
28
31
29 .selector-chosen h2 {
32 .selector-chosen h2 {
30 background: #79aec8;
33 background: var(--primary);
31 color: #fff;
34 color: var(--header-link-color);
32 }
35 }
33
36
34 .selector .selector-available h2 {
37 .selector .selector-available h2 {
35 background: #f8f8f8;
38 background: var(--darkened-bg);
36 color: #666;
39 color: var(--body-quiet-color);
37 }
40 }
38
41
39 .selector .selector-filter {
42 .selector .selector-filter {
40 background: white;
43 border: 1px solid var(--border-color);
41 border: 1px solid #ccc;
42 border-width: 0 1px;
44 border-width: 0 1px;
43 padding: 8px;
45 padding: 8px;
44 color: #999;
46 color: var(--body-quiet-color);
45 font-size: 10px;
47 font-size: 0.625rem;
46 margin: 0;
48 margin: 0;
47 text-align: left;
49 text-align: left;
48 }
50 }
@@ -64,12 +66,13
64 }
66 }
65
67
66 .selector ul.selector-chooser {
68 .selector ul.selector-chooser {
67 float: left;
69 align-self: center;
68 width: 22px;
70 width: 22px;
69 background-color: #eee;
71 background-color: var(--selected-bg);
70 border-radius: 10px;
72 border-radius: 10px;
71 margin: 10em 5px 0 5px;
73 margin: 0 5px;
72 padding: 0;
74 padding: 0;
75 transform: translateY(-17px);
73 }
76 }
74
77
75 .selector-chooser li {
78 .selector-chooser li {
@@ -91,7 +94,7
91 text-indent: -3000px;
94 text-indent: -3000px;
92 overflow: hidden;
95 overflow: hidden;
93 cursor: default;
96 cursor: default;
94 opacity: 0.3;
97 opacity: 0.55;
95 }
98 }
96
99
97 .active.selector-add, .active.selector-remove {
100 .active.selector-add, .active.selector-remove {
@@ -126,14 +129,14 a.selector-chooseall, a.selector-clearall {
126 overflow: hidden;
129 overflow: hidden;
127 font-weight: bold;
130 font-weight: bold;
128 line-height: 16px;
131 line-height: 16px;
129 color: #666;
132 color: var(--body-quiet-color);
130 text-decoration: none;
133 text-decoration: none;
131 opacity: 0.3;
134 opacity: 0.55;
132 }
135 }
133
136
134 a.active.selector-chooseall:focus, a.active.selector-clearall:focus,
137 a.active.selector-chooseall:focus, a.active.selector-clearall:focus,
135 a.active.selector-chooseall:hover, a.active.selector-clearall:hover {
138 a.active.selector-chooseall:hover, a.active.selector-clearall:hover {
136 color: #447e9b;
139 color: var(--link-fg);
137 }
140 }
138
141
139 a.active.selector-chooseall, a.active.selector-clearall {
142 a.active.selector-chooseall, a.active.selector-clearall {
@@ -169,6 +172,7 a.active.selector-clearall:focus, a.active.selector-clearall:hover {
169 .stacked {
172 .stacked {
170 float: left;
173 float: left;
171 width: 490px;
174 width: 490px;
175 display: block;
172 }
176 }
173
177
174 .stacked select {
178 .stacked select {
@@ -194,6 +198,7 a.active.selector-clearall:focus, a.active.selector-clearall:hover {
194 margin: 0 0 10px 40%;
198 margin: 0 0 10px 40%;
195 background-color: #eee;
199 background-color: #eee;
196 border-radius: 10px;
200 border-radius: 10px;
201 transform: none;
197 }
202 }
198
203
199 .stacked .selector-chooser li {
204 .stacked .selector-chooser li {
@@ -211,6 +216,11 a.active.selector-clearall:focus, a.active.selector-clearall:hover {
211 }
216 }
212
217
213 .stacked .active.selector-add {
218 .stacked .active.selector-add {
219 background-position: 0 -32px;
220 cursor: pointer;
221 }
222
223 .stacked .active.selector-add:focus, .stacked .active.selector-add:hover {
214 background-position: 0 -48px;
224 background-position: 0 -48px;
215 cursor: pointer;
225 cursor: pointer;
216 }
226 }
@@ -221,6 +231,11 a.active.selector-clearall:focus, a.active.selector-clearall:hover {
221 }
231 }
222
232
223 .stacked .active.selector-remove {
233 .stacked .active.selector-remove {
234 background-position: 0 0px;
235 cursor: pointer;
236 }
237
238 .stacked .active.selector-remove:focus, .stacked .active.selector-remove:hover {
224 background-position: 0 -16px;
239 background-position: 0 -16px;
225 cursor: pointer;
240 cursor: pointer;
226 }
241 }
@@ -251,25 +266,24 p.datetime {
251 line-height: 20px;
266 line-height: 20px;
252 margin: 0;
267 margin: 0;
253 padding: 0;
268 padding: 0;
254 color: #666;
269 color: var(--body-quiet-color);
255 font-weight: bold;
270 font-weight: bold;
256 }
271 }
257
272
258 .datetime span {
273 .datetime span {
259 white-space: nowrap;
274 white-space: nowrap;
260 font-weight: normal;
275 font-weight: normal;
261 font-size: 11px;
276 font-size: 0.6875rem;
262 color: #ccc;
277 color: var(--body-quiet-color);
263 }
278 }
264
279
265 .datetime input, .form-row .datetime input.vDateField, .form-row .datetime input.vTimeField {
280 .datetime input, .form-row .datetime input.vDateField, .form-row .datetime input.vTimeField {
266 min-width: 0;
267 margin-left: 5px;
281 margin-left: 5px;
268 margin-bottom: 4px;
282 margin-bottom: 4px;
269 }
283 }
270
284
271 table p.datetime {
285 table p.datetime {
272 font-size: 11px;
286 font-size: 0.6875rem;
273 margin-left: 0;
287 margin-left: 0;
274 padding-left: 0;
288 padding-left: 0;
275 }
289 }
@@ -303,8 +317,8 table p.datetime {
303 }
317 }
304
318
305 .timezonewarning {
319 .timezonewarning {
306 font-size: 11px;
320 font-size: 0.6875rem;
307 color: #999;
321 color: var(--body-quiet-color);
308 }
322 }
309
323
310 /* URL */
324 /* URL */
@@ -313,8 +327,8 p.url {
313 line-height: 20px;
327 line-height: 20px;
314 margin: 0;
328 margin: 0;
315 padding: 0;
329 padding: 0;
316 color: #666;
330 color: var(--body-quiet-color);
317 font-size: 11px;
331 font-size: 0.6875rem;
318 font-weight: bold;
332 font-weight: bold;
319 }
333 }
320
334
@@ -328,8 +342,8 p.file-upload {
328 line-height: 20px;
342 line-height: 20px;
329 margin: 0;
343 margin: 0;
330 padding: 0;
344 padding: 0;
331 color: #666;
345 color: var(--body-quiet-color);
332 font-size: 11px;
346 font-size: 0.6875rem;
333 font-weight: bold;
347 font-weight: bold;
334 }
348 }
335
349
@@ -346,8 +360,8 p.file-upload {
346 }
360 }
347
361
348 span.clearable-file-input label {
362 span.clearable-file-input label {
349 color: #333;
363 color: var(--body-fg);
350 font-size: 11px;
364 font-size: 0.6875rem;
351 display: inline;
365 display: inline;
352 float: none;
366 float: none;
353 }
367 }
@@ -356,11 +370,12 span.clearable-file-input label {
356
370
357 .calendarbox, .clockbox {
371 .calendarbox, .clockbox {
358 margin: 5px auto;
372 margin: 5px auto;
359 font-size: 12px;
373 font-size: 0.75rem;
360 width: 19em;
374 width: 19em;
361 text-align: center;
375 text-align: center;
362 background: white;
376 background: var(--body-bg);
363 border: 1px solid #ddd;
377 color: var(--body-fg);
378 border: 1px solid var(--hairline-color);
364 border-radius: 4px;
379 border-radius: 4px;
365 box-shadow: 0 2px 4px rgba(0, 0, 0, 0.15);
380 box-shadow: 0 2px 4px rgba(0, 0, 0, 0.15);
366 overflow: hidden;
381 overflow: hidden;
@@ -388,38 +403,38 span.clearable-file-input label {
388 margin: 0;
403 margin: 0;
389 text-align: center;
404 text-align: center;
390 border-top: none;
405 border-top: none;
391 background: #f5dd5d;
392 font-weight: 700;
406 font-weight: 700;
393 font-size: 12px;
407 font-size: 0.75rem;
394 color: #333;
408 color: #333;
409 background: var(--accent);
395 }
410 }
396
411
397 .calendar th {
412 .calendar th {
398 padding: 8px 5px;
413 padding: 8px 5px;
399 background: #f8f8f8;
414 background: var(--darkened-bg);
400 border-bottom: 1px solid #ddd;
415 border-bottom: 1px solid var(--border-color);
401 font-weight: 400;
416 font-weight: 400;
402 font-size: 12px;
417 font-size: 0.75rem;
403 text-align: center;
418 text-align: center;
404 color: #666;
419 color: var(--body-quiet-color);
405 }
420 }
406
421
407 .calendar td {
422 .calendar td {
408 font-weight: 400;
423 font-weight: 400;
409 font-size: 12px;
424 font-size: 0.75rem;
410 text-align: center;
425 text-align: center;
411 padding: 0;
426 padding: 0;
412 border-top: 1px solid #eee;
427 border-top: 1px solid var(--hairline-color);
413 border-bottom: none;
428 border-bottom: none;
414 }
429 }
415
430
416 .calendar td.selected a {
431 .calendar td.selected a {
417 background: #79aec8;
432 background: var(--primary);
418 color: #fff;
433 color: var(--button-fg);
419 }
434 }
420
435
421 .calendar td.nonday {
436 .calendar td.nonday {
422 background: #f8f8f8;
437 background: var(--darkened-bg);
423 }
438 }
424
439
425 .calendar td.today a {
440 .calendar td.today a {
@@ -431,22 +446,22 span.clearable-file-input label {
431 font-weight: 400;
446 font-weight: 400;
432 padding: 6px;
447 padding: 6px;
433 text-decoration: none;
448 text-decoration: none;
434 color: #444;
449 color: var(--body-quiet-color);
435 }
450 }
436
451
437 .calendar td a:focus, .timelist a:focus,
452 .calendar td a:focus, .timelist a:focus,
438 .calendar td a:hover, .timelist a:hover {
453 .calendar td a:hover, .timelist a:hover {
439 background: #79aec8;
454 background: var(--primary);
440 color: white;
455 color: white;
441 }
456 }
442
457
443 .calendar td a:active, .timelist a:active {
458 .calendar td a:active, .timelist a:active {
444 background: #417690;
459 background: var(--header-bg);
445 color: white;
460 color: white;
446 }
461 }
447
462
448 .calendarnav {
463 .calendarnav {
449 font-size: 10px;
464 font-size: 0.625rem;
450 text-align: center;
465 text-align: center;
451 color: #ccc;
466 color: #ccc;
452 margin: 0;
467 margin: 0;
@@ -455,16 +470,16 span.clearable-file-input label {
455
470
456 .calendarnav a:link, #calendarnav a:visited,
471 .calendarnav a:link, #calendarnav a:visited,
457 #calendarnav a:focus, #calendarnav a:hover {
472 #calendarnav a:focus, #calendarnav a:hover {
458 color: #999;
473 color: var(--body-quiet-color);
459 }
474 }
460
475
461 .calendar-shortcuts {
476 .calendar-shortcuts {
462 background: white;
477 background: var(--body-bg);
463 font-size: 11px;
478 color: var(--body-quiet-color);
479 font-size: 0.6875rem;
464 line-height: 11px;
480 line-height: 11px;
465 border-top: 1px solid #eee;
481 border-top: 1px solid var(--hairline-color);
466 padding: 8px 0;
482 padding: 8px 0;
467 color: #ccc;
468 }
483 }
469
484
470 .calendarbox .calendarnav-previous, .calendarbox .calendarnav-next {
485 .calendarbox .calendarnav-previous, .calendarbox .calendarnav-next {
@@ -500,10 +515,10 span.clearable-file-input label {
500 .calendar-cancel {
515 .calendar-cancel {
501 margin: 0;
516 margin: 0;
502 padding: 4px 0;
517 padding: 4px 0;
503 font-size: 12px;
518 font-size: 0.75rem;
504 background: #eee;
519 background: #eee;
505 border-top: 1px solid #ddd;
520 border-top: 1px solid var(--border-color);
506 color: #333;
521 color: var(--body-fg);
507 }
522 }
508
523
509 .calendar-cancel:focus, .calendar-cancel:hover {
524 .calendar-cancel:focus, .calendar-cancel:hover {
@@ -1,64 +1,50
1 (function($) {
1 'use strict';
2 'use strict';
2 {
3 var SelectBox = {
3 const SelectBox = {
4 cache: {},
4 cache: {},
5 init: function(id) {
5 init: function(id) {
6 var box = document.getElementById(id);
6 const box = document.getElementById(id);
7 var node;
8 SelectBox.cache[id] = [];
7 SelectBox.cache[id] = [];
9 var cache = SelectBox.cache[id];
8 const cache = SelectBox.cache[id];
10 var boxOptions = box.options;
9 for (const node of box.options) {
11 var boxOptionsLength = boxOptions.length;
12 for (var i = 0, j = boxOptionsLength; i < j; i++) {
13 node = boxOptions[i];
14 cache.push({value: node.value, text: node.text, displayed: 1});
10 cache.push({value: node.value, text: node.text, displayed: 1});
15 }
11 }
16 },
12 },
17 redisplay: function(id) {
13 redisplay: function(id) {
18 // Repopulate HTML select box from cache
14 // Repopulate HTML select box from cache
19 var box = document.getElementById(id);
15 const box = document.getElementById(id);
20 var node;
16 const scroll_value_from_top = box.scrollTop;
21 $(box).empty(); // clear all options
17 box.innerHTML = '';
22 var new_options = box.outerHTML.slice(0, -9); // grab just the opening tag
18 for (const node of SelectBox.cache[id]) {
23 var cache = SelectBox.cache[id];
24 for (var i = 0, j = cache.length; i < j; i++) {
25 node = cache[i];
26 if (node.displayed) {
19 if (node.displayed) {
27 var new_option = new Option(node.text, node.value, false, false);
20 const new_option = new Option(node.text, node.value, false, false);
28 // Shows a tooltip when hovering over the option
21 // Shows a tooltip when hovering over the option
29 new_option.setAttribute("title", node.text);
22 new_option.title = node.text;
30 new_options += new_option.outerHTML;
23 box.appendChild(new_option);
31 }
24 }
32 }
25 }
33 new_options += '</select>';
26 box.scrollTop = scroll_value_from_top;
34 box.outerHTML = new_options;
35 },
27 },
36 filter: function(id, text) {
28 filter: function(id, text) {
37 // Redisplay the HTML select box, displaying only the choices containing ALL
29 // Redisplay the HTML select box, displaying only the choices containing ALL
38 // the words in text. (It's an AND search.)
30 // the words in text. (It's an AND search.)
39 var tokens = text.toLowerCase().split(/\s+/);
31 const tokens = text.toLowerCase().split(/\s+/);
40 var node, token;
32 for (const node of SelectBox.cache[id]) {
41 var cache = SelectBox.cache[id];
42 for (var i = 0, j = cache.length; i < j; i++) {
43 node = cache[i];
44 node.displayed = 1;
33 node.displayed = 1;
45 var node_text = node.text.toLowerCase();
34 const node_text = node.text.toLowerCase();
46 var numTokens = tokens.length;
35 for (const token of tokens) {
47 for (var k = 0; k < numTokens; k++) {
36 if (!node_text.includes(token)) {
48 token = tokens[k];
49 if (node_text.indexOf(token) === -1) {
50 node.displayed = 0;
37 node.displayed = 0;
51 break; // Once the first token isn't found we're done
38 break; // Once the first token isn't found we're done
52 }
39 }
53 }
40 }
54 }
41 }
55 SelectBox.redisplay(id);
42 SelectBox.redisplay(id);
56 },
43 },
57 delete_from_cache: function(id, value) {
44 delete_from_cache: function(id, value) {
58 var node, delete_index = null;
45 let delete_index = null;
59 var cache = SelectBox.cache[id];
46 const cache = SelectBox.cache[id];
60 for (var i = 0, j = cache.length; i < j; i++) {
47 for (const [i, node] of cache.entries()) {
61 node = cache[i];
62 if (node.value === value) {
48 if (node.value === value) {
63 delete_index = i;
49 delete_index = i;
64 break;
50 break;
@@ -71,10 +57,7
71 },
57 },
72 cache_contains: function(id, value) {
58 cache_contains: function(id, value) {
73 // Check if an item is contained in the cache
59 // Check if an item is contained in the cache
74 var node;
60 for (const node of SelectBox.cache[id]) {
75 var cache = SelectBox.cache[id];
76 for (var i = 0, j = cache.length; i < j; i++) {
77 node = cache[i];
78 if (node.value === value) {
61 if (node.value === value) {
79 return true;
62 return true;
80 }
63 }
@@ -82,13 +65,9
82 return false;
65 return false;
83 },
66 },
84 move: function(from, to) {
67 move: function(from, to) {
85 var from_box = document.getElementById(from);
68 const from_box = document.getElementById(from);
86 var option;
69 for (const option of from_box.options) {
87 var boxOptions = from_box.options;
70 const option_value = option.value;
88 var boxOptionsLength = boxOptions.length;
89 for (var i = 0, j = boxOptionsLength; i < j; i++) {
90 option = boxOptions[i];
91 var option_value = option.value;
92 if (option.selected && SelectBox.cache_contains(from, option_value)) {
71 if (option.selected && SelectBox.cache_contains(from, option_value)) {
93 SelectBox.add_to_cache(to, {value: option_value, text: option.text, displayed: 1});
72 SelectBox.add_to_cache(to, {value: option_value, text: option.text, displayed: 1});
94 SelectBox.delete_from_cache(from, option_value);
73 SelectBox.delete_from_cache(from, option_value);
@@ -98,13 +77,9
98 SelectBox.redisplay(to);
77 SelectBox.redisplay(to);
99 },
78 },
100 move_all: function(from, to) {
79 move_all: function(from, to) {
101 var from_box = document.getElementById(from);
80 const from_box = document.getElementById(from);
102 var option;
81 for (const option of from_box.options) {
103 var boxOptions = from_box.options;
82 const option_value = option.value;
104 var boxOptionsLength = boxOptions.length;
105 for (var i = 0, j = boxOptionsLength; i < j; i++) {
106 option = boxOptions[i];
107 var option_value = option.value;
108 if (SelectBox.cache_contains(from, option_value)) {
83 if (SelectBox.cache_contains(from, option_value)) {
109 SelectBox.add_to_cache(to, {value: option_value, text: option.text, displayed: 1});
84 SelectBox.add_to_cache(to, {value: option_value, text: option.text, displayed: 1});
110 SelectBox.delete_from_cache(from, option_value);
85 SelectBox.delete_from_cache(from, option_value);
@@ -117,28 +92,21
117 SelectBox.cache[id].sort(function(a, b) {
92 SelectBox.cache[id].sort(function(a, b) {
118 a = a.text.toLowerCase();
93 a = a.text.toLowerCase();
119 b = b.text.toLowerCase();
94 b = b.text.toLowerCase();
120 try {
95 if (a > b) {
121 if (a > b) {
96 return 1;
122 return 1;
123 }
124 if (a < b) {
125 return -1;
126 }
127 }
97 }
128 catch (e) {
98 if (a < b) {
129 // silently fail on IE 'unknown' exception
99 return -1;
130 }
100 }
131 return 0;
101 return 0;
132 } );
102 } );
133 },
103 },
134 select_all: function(id) {
104 select_all: function(id) {
135 var box = document.getElementById(id);
105 const box = document.getElementById(id);
136 var boxOptions = box.options;
106 for (const option of box.options) {
137 var boxOptionsLength = boxOptions.length;
107 option.selected = true;
138 for (var i = 0; i < boxOptionsLength; i++) {
139 boxOptions[i].selected = 'selected';
140 }
108 }
141 }
109 }
142 };
110 };
143 window.SelectBox = SelectBox;
111 window.SelectBox = SelectBox;
144 })(django.jQuery);
112 }
@@ -2,49 +2,40
2 /*
2 /*
3 SelectFilter2 - Turns a multiple-select box into a filter interface.
3 SelectFilter2 - Turns a multiple-select box into a filter interface.
4
4
5 Requires jQuery, core.js, and SelectBox.js.
5 Requires core.js and SelectBox.js.
6 */
6 */
7 (function($) {
7 'use strict';
8 'use strict';
8 {
9 function findForm(node) {
10 // returns the node of the form containing the given node
11 if (node.tagName.toLowerCase() !== 'form') {
12 return findForm(node.parentNode);
13 }
14 return node;
15 }
16
17 window.SelectFilter = {
9 window.SelectFilter = {
18 init: function(field_id, field_name, is_stacked) {
10 init: function(field_id, field_name, is_stacked) {
19 if (field_id.match(/__prefix__/)) {
11 if (field_id.match(/__prefix__/)) {
20 // Don't initialize on empty forms.
12 // Don't initialize on empty forms.
21 return;
13 return;
22 }
14 }
23 var from_box = document.getElementById(field_id);
15 const from_box = document.getElementById(field_id);
24 from_box.id += '_from'; // change its ID
16 from_box.id += '_from'; // change its ID
25 from_box.className = 'filtered';
17 from_box.className = 'filtered';
26
18
27 var ps = from_box.parentNode.getElementsByTagName('p');
19 for (const p of from_box.parentNode.getElementsByTagName('p')) {
28 for (var i = 0; i < ps.length; i++) {
20 if (p.classList.contains("info")) {
29 if (ps[i].className.indexOf("info") !== -1) {
30 // Remove <p class="info">, because it just gets in the way.
21 // Remove <p class="info">, because it just gets in the way.
31 from_box.parentNode.removeChild(ps[i]);
22 from_box.parentNode.removeChild(p);
32 } else if (ps[i].className.indexOf("help") !== -1) {
23 } else if (p.classList.contains("help")) {
33 // Move help text up to the top so it isn't below the select
24 // Move help text up to the top so it isn't below the select
34 // boxes or wrapped off on the side to the right of the add
25 // boxes or wrapped off on the side to the right of the add
35 // button:
26 // button:
36 from_box.parentNode.insertBefore(ps[i], from_box.parentNode.firstChild);
27 from_box.parentNode.insertBefore(p, from_box.parentNode.firstChild);
37 }
28 }
38 }
29 }
39
30
40 // <div class="selector"> or <div class="selector stacked">
31 // <div class="selector"> or <div class="selector stacked">
41 var selector_div = quickElement('div', from_box.parentNode);
32 const selector_div = quickElement('div', from_box.parentNode);
42 selector_div.className = is_stacked ? 'selector stacked' : 'selector';
33 selector_div.className = is_stacked ? 'selector stacked' : 'selector';
43
34
44 // <div class="selector-available">
35 // <div class="selector-available">
45 var selector_available = quickElement('div', selector_div);
36 const selector_available = quickElement('div', selector_div);
46 selector_available.className = 'selector-available';
37 selector_available.className = 'selector-available';
47 var title_available = quickElement('h2', selector_available, interpolate(gettext('Available %s') + ' ', [field_name]));
38 const title_available = quickElement('h2', selector_available, interpolate(gettext('Available %s') + ' ', [field_name]));
48 quickElement(
39 quickElement(
49 'span', title_available, '',
40 'span', title_available, '',
50 'class', 'help help-tooltip help-icon',
41 'class', 'help help-tooltip help-icon',
@@ -58,10 +49,10 Requires jQuery, core.js, and SelectBox.js.
58 )
49 )
59 );
50 );
60
51
61 var filter_p = quickElement('p', selector_available, '', 'id', field_id + '_filter');
52 const filter_p = quickElement('p', selector_available, '', 'id', field_id + '_filter');
62 filter_p.className = 'selector-filter';
53 filter_p.className = 'selector-filter';
63
54
64 var search_filter_label = quickElement('label', filter_p, '', 'for', field_id + '_input');
55 const search_filter_label = quickElement('label', filter_p, '', 'for', field_id + '_input');
65
56
66 quickElement(
57 quickElement(
67 'span', search_filter_label, '',
58 'span', search_filter_label, '',
@@ -71,25 +62,25 Requires jQuery, core.js, and SelectBox.js.
71
62
72 filter_p.appendChild(document.createTextNode(' '));
63 filter_p.appendChild(document.createTextNode(' '));
73
64
74 var filter_input = quickElement('input', filter_p, '', 'type', 'text', 'placeholder', gettext("Filter"));
65 const filter_input = quickElement('input', filter_p, '', 'type', 'text', 'placeholder', gettext("Filter"));
75 filter_input.id = field_id + '_input';
66 filter_input.id = field_id + '_input';
76
67
77 selector_available.appendChild(from_box);
68 selector_available.appendChild(from_box);
78 var choose_all = quickElement('a', selector_available, gettext('Choose all'), 'title', interpolate(gettext('Click to choose all %s at once.'), [field_name]), 'href', '#', 'id', field_id + '_add_all_link');
69 const choose_all = quickElement('a', selector_available, gettext('Choose all'), 'title', interpolate(gettext('Click to choose all %s at once.'), [field_name]), 'href', '#', 'id', field_id + '_add_all_link');
79 choose_all.className = 'selector-chooseall';
70 choose_all.className = 'selector-chooseall';
80
71
81 // <ul class="selector-chooser">
72 // <ul class="selector-chooser">
82 var selector_chooser = quickElement('ul', selector_div);
73 const selector_chooser = quickElement('ul', selector_div);
83 selector_chooser.className = 'selector-chooser';
74 selector_chooser.className = 'selector-chooser';
84 var add_link = quickElement('a', quickElement('li', selector_chooser), gettext('Choose'), 'title', gettext('Choose'), 'href', '#', 'id', field_id + '_add_link');
75 const add_link = quickElement('a', quickElement('li', selector_chooser), gettext('Choose'), 'title', gettext('Choose'), 'href', '#', 'id', field_id + '_add_link');
85 add_link.className = 'selector-add';
76 add_link.className = 'selector-add';
86 var remove_link = quickElement('a', quickElement('li', selector_chooser), gettext('Remove'), 'title', gettext('Remove'), 'href', '#', 'id', field_id + '_remove_link');
77 const remove_link = quickElement('a', quickElement('li', selector_chooser), gettext('Remove'), 'title', gettext('Remove'), 'href', '#', 'id', field_id + '_remove_link');
87 remove_link.className = 'selector-remove';
78 remove_link.className = 'selector-remove';
88
79
89 // <div class="selector-chosen">
80 // <div class="selector-chosen">
90 var selector_chosen = quickElement('div', selector_div);
81 const selector_chosen = quickElement('div', selector_div);
91 selector_chosen.className = 'selector-chosen';
82 selector_chosen.className = 'selector-chosen';
92 var title_chosen = quickElement('h2', selector_chosen, interpolate(gettext('Chosen %s') + ' ', [field_name]));
83 const title_chosen = quickElement('h2', selector_chosen, interpolate(gettext('Chosen %s') + ' ', [field_name]));
93 quickElement(
84 quickElement(
94 'span', title_chosen, '',
85 'span', title_chosen, '',
95 'class', 'help help-tooltip help-icon',
86 'class', 'help help-tooltip help-icon',
@@ -103,16 +94,16 Requires jQuery, core.js, and SelectBox.js.
103 )
94 )
104 );
95 );
105
96
106 var to_box = quickElement('select', selector_chosen, '', 'id', field_id + '_to', 'multiple', 'multiple', 'size', from_box.size, 'name', from_box.getAttribute('name'));
97 const to_box = quickElement('select', selector_chosen, '', 'id', field_id + '_to', 'multiple', '', 'size', from_box.size, 'name', from_box.name);
107 to_box.className = 'filtered';
98 to_box.className = 'filtered';
108 var clear_all = quickElement('a', selector_chosen, gettext('Remove all'), 'title', interpolate(gettext('Click to remove all chosen %s at once.'), [field_name]), 'href', '#', 'id', field_id + '_remove_all_link');
99 const clear_all = quickElement('a', selector_chosen, gettext('Remove all'), 'title', interpolate(gettext('Click to remove all chosen %s at once.'), [field_name]), 'href', '#', 'id', field_id + '_remove_all_link');
109 clear_all.className = 'selector-clearall';
100 clear_all.className = 'selector-clearall';
110
101
111 from_box.setAttribute('name', from_box.getAttribute('name') + '_old');
102 from_box.name = from_box.name + '_old';
112
103
113 // Set up the JavaScript event handlers for the select box filter interface
104 // Set up the JavaScript event handlers for the select box filter interface
114 var move_selection = function(e, elem, move_func, from, to) {
105 const move_selection = function(e, elem, move_func, from, to) {
115 if (elem.className.indexOf('active') !== -1) {
106 if (elem.classList.contains('active')) {
116 move_func(from, to);
107 move_func(from, to);
117 SelectFilter.refresh_icons(field_id);
108 SelectFilter.refresh_icons(field_id);
118 }
109 }
@@ -154,7 +145,7 Requires jQuery, core.js, and SelectBox.js.
154 SelectFilter.refresh_icons(field_id);
145 SelectFilter.refresh_icons(field_id);
155 }
146 }
156 });
147 });
157 findForm(from_box).addEventListener('submit', function() {
148 from_box.closest('form').addEventListener('submit', function() {
158 SelectBox.select_all(field_id + '_to');
149 SelectBox.select_all(field_id + '_to');
159 });
150 });
160 SelectBox.init(field_id + '_from');
151 SelectBox.init(field_id + '_from');
@@ -162,66 +153,50 Requires jQuery, core.js, and SelectBox.js.
162 // Move selected from_box options to to_box
153 // Move selected from_box options to to_box
163 SelectBox.move(field_id + '_from', field_id + '_to');
154 SelectBox.move(field_id + '_from', field_id + '_to');
164
155
165 if (!is_stacked) {
166 // In horizontal mode, give the same height to the two boxes.
167 var j_from_box = $('#' + field_id + '_from');
168 var j_to_box = $('#' + field_id + '_to');
169 j_to_box.height($(filter_p).outerHeight() + j_from_box.outerHeight());
170 }
171
172 // Initial icon refresh
156 // Initial icon refresh
173 SelectFilter.refresh_icons(field_id);
157 SelectFilter.refresh_icons(field_id);
174 },
158 },
175 any_selected: function(field) {
159 any_selected: function(field) {
176 var any_selected = false;
160 // Temporarily add the required attribute and check validity.
177 try {
161 field.required = true;
178 // Temporarily add the required attribute and check validity.
162 const any_selected = field.checkValidity();
179 // This is much faster in WebKit browsers than the fallback.
163 field.required = false;
180 field.attr('required', 'required');
181 any_selected = field.is(':valid');
182 field.removeAttr('required');
183 } catch (e) {
184 // Browsers that don't support :valid (IE < 10)
185 any_selected = field.find('option:selected').length > 0;
186 }
187 return any_selected;
164 return any_selected;
188 },
165 },
189 refresh_icons: function(field_id) {
166 refresh_icons: function(field_id) {
190 var from = $('#' + field_id + '_from');
167 const from = document.getElementById(field_id + '_from');
191 var to = $('#' + field_id + '_to');
168 const to = document.getElementById(field_id + '_to');
192 // Active if at least one item is selected
169 // Active if at least one item is selected
193 $('#' + field_id + '_add_link').toggleClass('active', SelectFilter.any_selected(from));
170 document.getElementById(field_id + '_add_link').classList.toggle('active', SelectFilter.any_selected(from));
194 $('#' + field_id + '_remove_link').toggleClass('active', SelectFilter.any_selected(to));
171 document.getElementById(field_id + '_remove_link').classList.toggle('active', SelectFilter.any_selected(to));
195 // Active if the corresponding box isn't empty
172 // Active if the corresponding box isn't empty
196 $('#' + field_id + '_add_all_link').toggleClass('active', from.find('option').length > 0);
173 document.getElementById(field_id + '_add_all_link').classList.toggle('active', from.querySelector('option'));
197 $('#' + field_id + '_remove_all_link').toggleClass('active', to.find('option').length > 0);
174 document.getElementById(field_id + '_remove_all_link').classList.toggle('active', to.querySelector('option'));
198 },
175 },
199 filter_key_press: function(event, field_id) {
176 filter_key_press: function(event, field_id) {
200 var from = document.getElementById(field_id + '_from');
177 const from = document.getElementById(field_id + '_from');
201 // don't submit form if user pressed Enter
178 // don't submit form if user pressed Enter
202 if ((event.which && event.which === 13) || (event.keyCode && event.keyCode === 13)) {
179 if ((event.which && event.which === 13) || (event.keyCode && event.keyCode === 13)) {
203 from.selectedIndex = 0;
180 from.selectedIndex = 0;
204 SelectBox.move(field_id + '_from', field_id + '_to');
181 SelectBox.move(field_id + '_from', field_id + '_to');
205 from.selectedIndex = 0;
182 from.selectedIndex = 0;
206 event.preventDefault();
183 event.preventDefault();
207 return false;
208 }
184 }
209 },
185 },
210 filter_key_up: function(event, field_id) {
186 filter_key_up: function(event, field_id) {
211 var from = document.getElementById(field_id + '_from');
187 const from = document.getElementById(field_id + '_from');
212 var temp = from.selectedIndex;
188 const temp = from.selectedIndex;
213 SelectBox.filter(field_id + '_from', document.getElementById(field_id + '_input').value);
189 SelectBox.filter(field_id + '_from', document.getElementById(field_id + '_input').value);
214 from.selectedIndex = temp;
190 from.selectedIndex = temp;
215 return true;
216 },
191 },
217 filter_key_down: function(event, field_id) {
192 filter_key_down: function(event, field_id) {
218 var from = document.getElementById(field_id + '_from');
193 const from = document.getElementById(field_id + '_from');
219 // right arrow -- move across
194 // right arrow -- move across
220 if ((event.which && event.which === 39) || (event.keyCode && event.keyCode === 39)) {
195 if ((event.which && event.which === 39) || (event.keyCode && event.keyCode === 39)) {
221 var old_index = from.selectedIndex;
196 const old_index = from.selectedIndex;
222 SelectBox.move(field_id + '_from', field_id + '_to');
197 SelectBox.move(field_id + '_from', field_id + '_to');
223 from.selectedIndex = (old_index === from.length) ? from.length - 1 : old_index;
198 from.selectedIndex = (old_index === from.length) ? from.length - 1 : old_index;
224 return false;
199 return;
225 }
200 }
226 // down arrow -- wrap around
201 // down arrow -- wrap around
227 if ((event.which && event.which === 40) || (event.keyCode && event.keyCode === 40)) {
202 if ((event.which && event.which === 40) || (event.keyCode && event.keyCode === 40)) {
@@ -231,16 +206,13 Requires jQuery, core.js, and SelectBox.js.
231 if ((event.which && event.which === 38) || (event.keyCode && event.keyCode === 38)) {
206 if ((event.which && event.which === 38) || (event.keyCode && event.keyCode === 38)) {
232 from.selectedIndex = (from.selectedIndex === 0) ? from.length - 1 : from.selectedIndex - 1;
207 from.selectedIndex = (from.selectedIndex === 0) ? from.length - 1 : from.selectedIndex - 1;
233 }
208 }
234 return true;
235 }
209 }
236 };
210 };
237
211
238 window.addEventListener('load', function(e) {
212 window.addEventListener('load', function(e) {
239 $('select.selectfilter, select.selectfilterstacked').each(function() {
213 document.querySelectorAll('select.selectfilter, select.selectfilterstacked').forEach(function(el) {
240 var $el = $(this),
214 const data = el.dataset;
241 data = $el.data();
215 SelectFilter.init(el.id, data.fieldName, parseInt(data.isStacked, 10));
242 SelectFilter.init($el.attr('id'), data.fieldName, parseInt(data.isStacked, 10));
243 });
216 });
244 });
217 });
245
218 }
246 })(django.jQuery);
@@ -1,153 +1,201
1 /*global gettext, interpolate, ngettext*/
1 /*global gettext, interpolate, ngettext*/
2 (function($) {
2 'use strict';
3 'use strict';
3 {
4 var lastChecked;
4 function show(selector) {
5
5 document.querySelectorAll(selector).forEach(function(el) {
6 $.fn.actions = function(opts) {
6 el.classList.remove('hidden');
7 var options = $.extend({}, $.fn.actions.defaults, opts);
7 });
8 var actionCheckboxes = $(this);
8 }
9 var list_editable_changed = false;
9
10 var showQuestion = function() {
10 function hide(selector) {
11 $(options.acrossClears).hide();
11 document.querySelectorAll(selector).forEach(function(el) {
12 $(options.acrossQuestions).show();
12 el.classList.add('hidden');
13 $(options.allContainer).hide();
13 });
14 },
14 }
15 showClear = function() {
15
16 $(options.acrossClears).show();
16 function showQuestion(options) {
17 $(options.acrossQuestions).hide();
17 hide(options.acrossClears);
18 $(options.actionContainer).toggleClass(options.selectedClass);
18 show(options.acrossQuestions);
19 $(options.allContainer).show();
19 hide(options.allContainer);
20 $(options.counterContainer).hide();
20 }
21 },
21
22 reset = function() {
22 function showClear(options) {
23 $(options.acrossClears).hide();
23 show(options.acrossClears);
24 $(options.acrossQuestions).hide();
24 hide(options.acrossQuestions);
25 $(options.allContainer).hide();
25 document.querySelector(options.actionContainer).classList.remove(options.selectedClass);
26 $(options.counterContainer).show();
26 show(options.allContainer);
27 },
27 hide(options.counterContainer);
28 clearAcross = function() {
28 }
29 reset();
29
30 $(options.acrossInput).val(0);
30 function reset(options) {
31 $(options.actionContainer).removeClass(options.selectedClass);
31 hide(options.acrossClears);
32 },
32 hide(options.acrossQuestions);
33 checker = function(checked) {
33 hide(options.allContainer);
34 if (checked) {
34 show(options.counterContainer);
35 showQuestion();
35 }
36 } else {
36
37 reset();
37 function clearAcross(options) {
38 }
38 reset(options);
39 $(actionCheckboxes).prop("checked", checked)
39 const acrossInputs = document.querySelectorAll(options.acrossInput);
40 .parent().parent().toggleClass(options.selectedClass, checked);
40 acrossInputs.forEach(function(acrossInput) {
41 },
41 acrossInput.value = 0;
42 updateCounter = function() {
42 });
43 var sel = $(actionCheckboxes).filter(":checked").length;
43 document.querySelector(options.actionContainer).classList.remove(options.selectedClass);
44 // data-actions-icnt is defined in the generated HTML
44 }
45 // and contains the total amount of objects in the queryset
45
46 var actions_icnt = $('.action-counter').data('actionsIcnt');
46 function checker(actionCheckboxes, options, checked) {
47 $(options.counterContainer).html(interpolate(
47 if (checked) {
48 showQuestion(options);
49 } else {
50 reset(options);
51 }
52 actionCheckboxes.forEach(function(el) {
53 el.checked = checked;
54 el.closest('tr').classList.toggle(options.selectedClass, checked);
55 });
56 }
57
58 function updateCounter(actionCheckboxes, options) {
59 const sel = Array.from(actionCheckboxes).filter(function(el) {
60 return el.checked;
61 }).length;
62 const counter = document.querySelector(options.counterContainer);
63 // data-actions-icnt is defined in the generated HTML
64 // and contains the total amount of objects in the queryset
65 const actions_icnt = Number(counter.dataset.actionsIcnt);
66 counter.textContent = interpolate(
48 ngettext('%(sel)s of %(cnt)s selected', '%(sel)s of %(cnt)s selected', sel), {
67 ngettext('%(sel)s of %(cnt)s selected', '%(sel)s of %(cnt)s selected', sel), {
49 sel: sel,
68 sel: sel,
50 cnt: actions_icnt
69 cnt: actions_icnt
51 }, true));
70 }, true);
52 $(options.allToggle).prop("checked", function() {
71 const allToggle = document.getElementById(options.allToggleId);
53 var value;
72 allToggle.checked = sel === actionCheckboxes.length;
54 if (sel === actionCheckboxes.length) {
73 if (allToggle.checked) {
55 value = true;
74 showQuestion(options);
56 showQuestion();
75 } else {
57 } else {
76 clearAcross(options);
58 value = false;
77 }
59 clearAcross();
78 }
60 }
79
61 return value;
80 const defaults = {
62 });
81 actionContainer: "div.actions",
63 };
82 counterContainer: "span.action-counter",
64 // Show counter by default
83 allContainer: "div.actions span.all",
65 $(options.counterContainer).show();
84 acrossInput: "div.actions input.select-across",
66 // Check state of checkboxes and reinit state if needed
85 acrossQuestions: "div.actions span.question",
67 $(this).filter(":checked").each(function(i) {
86 acrossClears: "div.actions span.clear",
68 $(this).parent().parent().toggleClass(options.selectedClass);
87 allToggleId: "action-toggle",
69 updateCounter();
88 selectedClass: "selected"
70 if ($(options.acrossInput).val() === 1) {
89 };
71 showClear();
90
72 }
91 window.Actions = function(actionCheckboxes, options) {
73 });
92 options = Object.assign({}, defaults, options);
74 $(options.allToggle).show().on('click', function() {
93 let list_editable_changed = false;
75 checker($(this).prop("checked"));
94 let lastChecked = null;
76 updateCounter();
95 let shiftPressed = false;
96
97 document.addEventListener('keydown', (event) => {
98 shiftPressed = event.shiftKey;
77 });
99 });
78 $("a", options.acrossQuestions).on('click', function(event) {
100
79 event.preventDefault();
101 document.addEventListener('keyup', (event) => {
80 $(options.acrossInput).val(1);
102 shiftPressed = event.shiftKey;
81 showClear();
82 });
103 });
83 $("a", options.acrossClears).on('click', function(event) {
104
84 event.preventDefault();
105 document.getElementById(options.allToggleId).addEventListener('click', function(event) {
85 $(options.allToggle).prop("checked", false);
106 checker(actionCheckboxes, options, this.checked);
86 clearAcross();
107 updateCounter(actionCheckboxes, options);
87 checker(0);
88 updateCounter();
89 });
108 });
90 lastChecked = null;
109
91 $(actionCheckboxes).on('click', function(event) {
110 document.querySelectorAll(options.acrossQuestions + " a").forEach(function(el) {
92 if (!event) { event = window.event; }
111 el.addEventListener('click', function(event) {
93 var target = event.target ? event.target : event.srcElement;
112 event.preventDefault();
94 if (lastChecked && $.data(lastChecked) !== $.data(target) && event.shiftKey === true) {
113 const acrossInputs = document.querySelectorAll(options.acrossInput);
95 var inrange = false;
114 acrossInputs.forEach(function(acrossInput) {
96 $(lastChecked).prop("checked", target.checked)
115 acrossInput.value = 1;
97 .parent().parent().toggleClass(options.selectedClass, target.checked);
98 $(actionCheckboxes).each(function() {
99 if ($.data(this) === $.data(lastChecked) || $.data(this) === $.data(target)) {
100 inrange = (inrange) ? false : true;
101 }
102 if (inrange) {
103 $(this).prop("checked", target.checked)
104 .parent().parent().toggleClass(options.selectedClass, target.checked);
105 }
106 });
116 });
107 }
117 showClear(options);
108 $(target).parent().parent().toggleClass(options.selectedClass, target.checked);
118 });
109 lastChecked = target;
110 updateCounter();
111 });
119 });
112 $('form#changelist-form table#result_list tr').on('change', 'td:gt(0) :input', function() {
120
113 list_editable_changed = true;
121 document.querySelectorAll(options.acrossClears + " a").forEach(function(el) {
122 el.addEventListener('click', function(event) {
123 event.preventDefault();
124 document.getElementById(options.allToggleId).checked = false;
125 clearAcross(options);
126 checker(actionCheckboxes, options, false);
127 updateCounter(actionCheckboxes, options);
128 });
114 });
129 });
115 $('form#changelist-form button[name="index"]').on('click', function(event) {
130
116 if (list_editable_changed) {
131 function affectedCheckboxes(target, withModifier) {
117 return confirm(gettext("You have unsaved changes on individual editable fields. If you run an action, your unsaved changes will be lost."));
132 const multiSelect = (lastChecked && withModifier && lastChecked !== target);
133 if (!multiSelect) {
134 return [target];
118 }
135 }
119 });
136 const checkboxes = Array.from(actionCheckboxes);
120 $('form#changelist-form input[name="_save"]').on('click', function(event) {
137 const targetIndex = checkboxes.findIndex(el => el === target);
121 var action_changed = false;
138 const lastCheckedIndex = checkboxes.findIndex(el => el === lastChecked);
122 $('select option:selected', options.actionContainer).each(function() {
139 const startIndex = Math.min(targetIndex, lastCheckedIndex);
123 if ($(this).val()) {
140 const endIndex = Math.max(targetIndex, lastCheckedIndex);
124 action_changed = true;
141 const filtered = checkboxes.filter((el, index) => (startIndex <= index) && (index <= endIndex));
142 return filtered;
143 };
144
145 Array.from(document.getElementById('result_list').tBodies).forEach(function(el) {
146 el.addEventListener('change', function(event) {
147 const target = event.target;
148 if (target.classList.contains('action-select')) {
149 const checkboxes = affectedCheckboxes(target, shiftPressed);
150 checker(checkboxes, options, target.checked);
151 updateCounter(actionCheckboxes, options);
152 lastChecked = target;
153 } else {
154 list_editable_changed = true;
125 }
155 }
126 });
156 });
127 if (action_changed) {
157 });
128 if (list_editable_changed) {
158
129 return confirm(gettext("You have selected an action, but you haven't saved your changes to individual fields yet. Please click OK to save. You'll need to re-run the action."));
159 document.querySelector('#changelist-form button[name=index]').addEventListener('click', function(event) {
130 } else {
160 if (list_editable_changed) {
131 return confirm(gettext("You have selected an action, and you haven't made any changes on individual fields. You're probably looking for the Go button rather than the Save button."));
161 const confirmed = confirm(gettext("You have unsaved changes on individual editable fields. If you run an action, your unsaved changes will be lost."));
162 if (!confirmed) {
163 event.preventDefault();
132 }
164 }
133 }
165 }
134 });
166 });
167
168 const el = document.querySelector('#changelist-form input[name=_save]');
169 // The button does not exist if no fields are editable.
170 if (el) {
171 el.addEventListener('click', function(event) {
172 if (document.querySelector('[name=action]').value) {
173 const text = list_editable_changed
174 ? gettext("You have selected an action, but you haven’t saved your changes to individual fields yet. Please click OK to save. You’ll need to re-run the action.")
175 : gettext("You have selected an action, and you haven’t made any changes on individual fields. You’re probably looking for the Go button rather than the Save button.");
176 if (!confirm(text)) {
177 event.preventDefault();
178 }
179 }
180 });
181 }
135 };
182 };
136 /* Setup plugin defaults */
183
137 $.fn.actions.defaults = {
184 // Call function fn when the DOM is loaded and ready. If it is already
138 actionContainer: "div.actions",
185 // loaded, call the function now.
139 counterContainer: "span.action-counter",
186 // http://youmightnotneedjquery.com/#ready
140 allContainer: "div.actions span.all",
187 function ready(fn) {
141 acrossInput: "div.actions input.select-across",
188 if (document.readyState !== 'loading') {
142 acrossQuestions: "div.actions span.question",
189 fn();
143 acrossClears: "div.actions span.clear",
190 } else {
144 allToggle: "#action-toggle",
191 document.addEventListener('DOMContentLoaded', fn);
145 selectedClass: "selected"
192 }
146 };
193 }
147 $(document).ready(function() {
194
148 var $actionsEls = $('tr input.action-select');
195 ready(function() {
149 if ($actionsEls.length > 0) {
196 const actionsEls = document.querySelectorAll('tr input.action-select');
150 $actionsEls.actions();
197 if (actionsEls.length > 0) {
198 Actions(actionsEls);
151 }
199 }
152 });
200 });
153 })(django.jQuery);
201 }
@@ -1,10 +1,10
1 /*global Calendar, findPosX, findPosY, getStyle, get_format, gettext, gettext_noop, interpolate, ngettext, quickElement*/
1 /*global Calendar, findPosX, findPosY, get_format, gettext, gettext_noop, interpolate, ngettext, quickElement*/
2 // Inserts shortcut buttons after all of the following:
2 // Inserts shortcut buttons after all of the following:
3 // <input type="text" class="vDateField">
3 // <input type="text" class="vDateField">
4 // <input type="text" class="vTimeField">
4 // <input type="text" class="vTimeField">
5 (function() {
5 'use strict';
6 'use strict';
6 {
7 var DateTimeShortcuts = {
7 const DateTimeShortcuts = {
8 calendars: [],
8 calendars: [],
9 calendarInputs: [],
9 calendarInputs: [],
10 clockInputs: [],
10 clockInputs: [],
@@ -20,29 +20,26
20 dismissClockFunc: [],
20 dismissClockFunc: [],
21 dismissCalendarFunc: [],
21 dismissCalendarFunc: [],
22 calendarDivName1: 'calendarbox', // name of calendar <div> that gets toggled
22 calendarDivName1: 'calendarbox', // name of calendar <div> that gets toggled
23 calendarDivName2: 'calendarin', // name of <div> that contains calendar
23 calendarDivName2: 'calendarin', // name of <div> that contains calendar
24 calendarLinkName: 'calendarlink',// name of the link that is used to toggle
24 calendarLinkName: 'calendarlink', // name of the link that is used to toggle
25 clockDivName: 'clockbox', // name of clock <div> that gets toggled
25 clockDivName: 'clockbox', // name of clock <div> that gets toggled
26 clockLinkName: 'clocklink', // name of the link that is used to toggle
26 clockLinkName: 'clocklink', // name of the link that is used to toggle
27 shortCutsClass: 'datetimeshortcuts', // class of the clock and cal shortcuts
27 shortCutsClass: 'datetimeshortcuts', // class of the clock and cal shortcuts
28 timezoneWarningClass: 'timezonewarning', // class of the warning for timezone mismatch
28 timezoneWarningClass: 'timezonewarning', // class of the warning for timezone mismatch
29 timezoneOffset: 0,
29 timezoneOffset: 0,
30 init: function() {
30 init: function() {
31 var body = document.getElementsByTagName('body')[0];
31 const serverOffset = document.body.dataset.adminUtcOffset;
32 var serverOffset = body.getAttribute('data-admin-utc-offset');
33 if (serverOffset) {
32 if (serverOffset) {
34 var localOffset = new Date().getTimezoneOffset() * -60;
33 const localOffset = new Date().getTimezoneOffset() * -60;
35 DateTimeShortcuts.timezoneOffset = localOffset - serverOffset;
34 DateTimeShortcuts.timezoneOffset = localOffset - serverOffset;
36 }
35 }
37
36
38 var inputs = document.getElementsByTagName('input');
37 for (const inp of document.getElementsByTagName('input')) {
39 for (var i = 0; i < inputs.length; i++) {
38 if (inp.type === 'text' && inp.classList.contains('vTimeField')) {
40 var inp = inputs[i];
41 if (inp.getAttribute('type') === 'text' && inp.className.match(/vTimeField/)) {
42 DateTimeShortcuts.addClock(inp);
39 DateTimeShortcuts.addClock(inp);
43 DateTimeShortcuts.addTimezoneWarning(inp);
40 DateTimeShortcuts.addTimezoneWarning(inp);
44 }
41 }
45 else if (inp.getAttribute('type') === 'text' && inp.className.match(/vDateField/)) {
42 else if (inp.type === 'text' && inp.classList.contains('vDateField')) {
46 DateTimeShortcuts.addCalendar(inp);
43 DateTimeShortcuts.addCalendar(inp);
47 DateTimeShortcuts.addTimezoneWarning(inp);
44 DateTimeShortcuts.addTimezoneWarning(inp);
48 }
45 }
@@ -50,11 +47,10
50 },
47 },
51 // Return the current time while accounting for the server timezone.
48 // Return the current time while accounting for the server timezone.
52 now: function() {
49 now: function() {
53 var body = document.getElementsByTagName('body')[0];
50 const serverOffset = document.body.dataset.adminUtcOffset;
54 var serverOffset = body.getAttribute('data-admin-utc-offset');
55 if (serverOffset) {
51 if (serverOffset) {
56 var localNow = new Date();
52 const localNow = new Date();
57 var localOffset = localNow.getTimezoneOffset() * -60;
53 const localOffset = localNow.getTimezoneOffset() * -60;
58 localNow.setTime(localNow.getTime() + 1000 * (serverOffset - localOffset));
54 localNow.setTime(localNow.getTime() + 1000 * (serverOffset - localOffset));
59 return localNow;
55 return localNow;
60 } else {
56 } else {
@@ -63,8 +59,8
63 },
59 },
64 // Add a warning when the time zone in the browser and backend do not match.
60 // Add a warning when the time zone in the browser and backend do not match.
65 addTimezoneWarning: function(inp) {
61 addTimezoneWarning: function(inp) {
66 var warningClass = DateTimeShortcuts.timezoneWarningClass;
62 const warningClass = DateTimeShortcuts.timezoneWarningClass;
67 var timezoneOffset = DateTimeShortcuts.timezoneOffset / 3600;
63 let timezoneOffset = DateTimeShortcuts.timezoneOffset / 3600;
68
64
69 // Only warn if there is a time zone mismatch.
65 // Only warn if there is a time zone mismatch.
70 if (!timezoneOffset) {
66 if (!timezoneOffset) {
@@ -76,7 +72,7
76 return;
72 return;
77 }
73 }
78
74
79 var message;
75 let message;
80 if (timezoneOffset > 0) {
76 if (timezoneOffset > 0) {
81 message = ngettext(
77 message = ngettext(
82 'Note: You are %s hour ahead of server time.',
78 'Note: You are %s hour ahead of server time.',
@@ -94,7 +90,7
94 }
90 }
95 message = interpolate(message, [timezoneOffset]);
91 message = interpolate(message, [timezoneOffset]);
96
92
97 var warning = document.createElement('span');
93 const warning = document.createElement('span');
98 warning.className = warningClass;
94 warning.className = warningClass;
99 warning.textContent = message;
95 warning.textContent = message;
100 inp.parentNode.appendChild(document.createElement('br'));
96 inp.parentNode.appendChild(document.createElement('br'));
@@ -102,23 +98,23
102 },
98 },
103 // Add clock widget to a given field
99 // Add clock widget to a given field
104 addClock: function(inp) {
100 addClock: function(inp) {
105 var num = DateTimeShortcuts.clockInputs.length;
101 const num = DateTimeShortcuts.clockInputs.length;
106 DateTimeShortcuts.clockInputs[num] = inp;
102 DateTimeShortcuts.clockInputs[num] = inp;
107 DateTimeShortcuts.dismissClockFunc[num] = function() { DateTimeShortcuts.dismissClock(num); return true; };
103 DateTimeShortcuts.dismissClockFunc[num] = function() { DateTimeShortcuts.dismissClock(num); return true; };
108
104
109 // Shortcut links (clock icon and "Now" link)
105 // Shortcut links (clock icon and "Now" link)
110 var shortcuts_span = document.createElement('span');
106 const shortcuts_span = document.createElement('span');
111 shortcuts_span.className = DateTimeShortcuts.shortCutsClass;
107 shortcuts_span.className = DateTimeShortcuts.shortCutsClass;
112 inp.parentNode.insertBefore(shortcuts_span, inp.nextSibling);
108 inp.parentNode.insertBefore(shortcuts_span, inp.nextSibling);
113 var now_link = document.createElement('a');
109 const now_link = document.createElement('a');
114 now_link.setAttribute('href', "#");
110 now_link.href = "#";
115 now_link.textContent = gettext('Now');
111 now_link.textContent = gettext('Now');
116 now_link.addEventListener('click', function(e) {
112 now_link.addEventListener('click', function(e) {
117 e.preventDefault();
113 e.preventDefault();
118 DateTimeShortcuts.handleClockQuicklink(num, -1);
114 DateTimeShortcuts.handleClockQuicklink(num, -1);
119 });
115 });
120 var clock_link = document.createElement('a');
116 const clock_link = document.createElement('a');
121 clock_link.setAttribute('href', '#');
117 clock_link.href = '#';
122 clock_link.id = DateTimeShortcuts.clockLinkName + num;
118 clock_link.id = DateTimeShortcuts.clockLinkName + num;
123 clock_link.addEventListener('click', function(e) {
119 clock_link.addEventListener('click', function(e) {
124 e.preventDefault();
120 e.preventDefault();
@@ -152,32 +148,32
152 // <p class="calendar-cancel"><a href="#">Cancel</a></p>
148 // <p class="calendar-cancel"><a href="#">Cancel</a></p>
153 // </div>
149 // </div>
154
150
155 var clock_box = document.createElement('div');
151 const clock_box = document.createElement('div');
156 clock_box.style.display = 'none';
152 clock_box.style.display = 'none';
157 clock_box.style.position = 'absolute';
153 clock_box.style.position = 'absolute';
158 clock_box.className = 'clockbox module';
154 clock_box.className = 'clockbox module';
159 clock_box.setAttribute('id', DateTimeShortcuts.clockDivName + num);
155 clock_box.id = DateTimeShortcuts.clockDivName + num;
160 document.body.appendChild(clock_box);
156 document.body.appendChild(clock_box);
161 clock_box.addEventListener('click', function(e) { e.stopPropagation(); });
157 clock_box.addEventListener('click', function(e) { e.stopPropagation(); });
162
158
163 quickElement('h2', clock_box, gettext('Choose a time'));
159 quickElement('h2', clock_box, gettext('Choose a time'));
164 var time_list = quickElement('ul', clock_box);
160 const time_list = quickElement('ul', clock_box);
165 time_list.className = 'timelist';
161 time_list.className = 'timelist';
166 // The list of choices can be overridden in JavaScript like this:
162 // The list of choices can be overridden in JavaScript like this:
167 // DateTimeShortcuts.clockHours.name = [['3 a.m.', 3]];
163 // DateTimeShortcuts.clockHours.name = [['3 a.m.', 3]];
168 // where name is the name attribute of the <input>.
164 // where name is the name attribute of the <input>.
169 var name = typeof DateTimeShortcuts.clockHours[inp.name] === 'undefined' ? 'default_' : inp.name;
165 const name = typeof DateTimeShortcuts.clockHours[inp.name] === 'undefined' ? 'default_' : inp.name;
170 DateTimeShortcuts.clockHours[name].forEach(function(element) {
166 DateTimeShortcuts.clockHours[name].forEach(function(element) {
171 var time_link = quickElement('a', quickElement('li', time_list), gettext(element[0]), 'href', '#');
167 const time_link = quickElement('a', quickElement('li', time_list), gettext(element[0]), 'href', '#');
172 time_link.addEventListener('click', function(e) {
168 time_link.addEventListener('click', function(e) {
173 e.preventDefault();
169 e.preventDefault();
174 DateTimeShortcuts.handleClockQuicklink(num, element[1]);
170 DateTimeShortcuts.handleClockQuicklink(num, element[1]);
175 });
171 });
176 });
172 });
177
173
178 var cancel_p = quickElement('p', clock_box);
174 const cancel_p = quickElement('p', clock_box);
179 cancel_p.className = 'calendar-cancel';
175 cancel_p.className = 'calendar-cancel';
180 var cancel_link = quickElement('a', cancel_p, gettext('Cancel'), 'href', '#');
176 const cancel_link = quickElement('a', cancel_p, gettext('Cancel'), 'href', '#');
181 cancel_link.addEventListener('click', function(e) {
177 cancel_link.addEventListener('click', function(e) {
182 e.preventDefault();
178 e.preventDefault();
183 DateTimeShortcuts.dismissClock(num);
179 DateTimeShortcuts.dismissClock(num);
@@ -192,19 +188,17
192 });
188 });
193 },
189 },
194 openClock: function(num) {
190 openClock: function(num) {
195 var clock_box = document.getElementById(DateTimeShortcuts.clockDivName + num);
191 const clock_box = document.getElementById(DateTimeShortcuts.clockDivName + num);
196 var clock_link = document.getElementById(DateTimeShortcuts.clockLinkName + num);
192 const clock_link = document.getElementById(DateTimeShortcuts.clockLinkName + num);
197
193
198 // Recalculate the clockbox position
194 // Recalculate the clockbox position
199 // is it left-to-right or right-to-left layout ?
195 // is it left-to-right or right-to-left layout ?
200 if (getStyle(document.body, 'direction') !== 'rtl') {
196 if (window.getComputedStyle(document.body).direction !== 'rtl') {
201 clock_box.style.left = findPosX(clock_link) + 17 + 'px';
197 clock_box.style.left = findPosX(clock_link) + 17 + 'px';
202 }
198 }
203 else {
199 else {
204 // since style's width is in em, it'd be tough to calculate
200 // since style's width is in em, it'd be tough to calculate
205 // px value of it. let's use an estimated px for now
201 // px value of it. let's use an estimated px for now
206 // TODO: IE returns wrong value for findPosX when in rtl mode
207 // (it returns as it was left aligned), needs to be fixed.
208 clock_box.style.left = findPosX(clock_link) - 110 + 'px';
202 clock_box.style.left = findPosX(clock_link) - 110 + 'px';
209 }
203 }
210 clock_box.style.top = Math.max(0, findPosY(clock_link) - 30) + 'px';
204 clock_box.style.top = Math.max(0, findPosY(clock_link) - 30) + 'px';
@@ -218,7 +212,7
218 document.removeEventListener('click', DateTimeShortcuts.dismissClockFunc[num]);
212 document.removeEventListener('click', DateTimeShortcuts.dismissClockFunc[num]);
219 },
213 },
220 handleClockQuicklink: function(num, val) {
214 handleClockQuicklink: function(num, val) {
221 var d;
215 let d;
222 if (val === -1) {
216 if (val === -1) {
223 d = DateTimeShortcuts.now();
217 d = DateTimeShortcuts.now();
224 }
218 }
@@ -231,24 +225,24
231 },
225 },
232 // Add calendar widget to a given field.
226 // Add calendar widget to a given field.
233 addCalendar: function(inp) {
227 addCalendar: function(inp) {
234 var num = DateTimeShortcuts.calendars.length;
228 const num = DateTimeShortcuts.calendars.length;
235
229
236 DateTimeShortcuts.calendarInputs[num] = inp;
230 DateTimeShortcuts.calendarInputs[num] = inp;
237 DateTimeShortcuts.dismissCalendarFunc[num] = function() { DateTimeShortcuts.dismissCalendar(num); return true; };
231 DateTimeShortcuts.dismissCalendarFunc[num] = function() { DateTimeShortcuts.dismissCalendar(num); return true; };
238
232
239 // Shortcut links (calendar icon and "Today" link)
233 // Shortcut links (calendar icon and "Today" link)
240 var shortcuts_span = document.createElement('span');
234 const shortcuts_span = document.createElement('span');
241 shortcuts_span.className = DateTimeShortcuts.shortCutsClass;
235 shortcuts_span.className = DateTimeShortcuts.shortCutsClass;
242 inp.parentNode.insertBefore(shortcuts_span, inp.nextSibling);
236 inp.parentNode.insertBefore(shortcuts_span, inp.nextSibling);
243 var today_link = document.createElement('a');
237 const today_link = document.createElement('a');
244 today_link.setAttribute('href', '#');
238 today_link.href = '#';
245 today_link.appendChild(document.createTextNode(gettext('Today')));
239 today_link.appendChild(document.createTextNode(gettext('Today')));
246 today_link.addEventListener('click', function(e) {
240 today_link.addEventListener('click', function(e) {
247 e.preventDefault();
241 e.preventDefault();
248 DateTimeShortcuts.handleCalendarQuickLink(num, 0);
242 DateTimeShortcuts.handleCalendarQuickLink(num, 0);
249 });
243 });
250 var cal_link = document.createElement('a');
244 const cal_link = document.createElement('a');
251 cal_link.setAttribute('href', '#');
245 cal_link.href = '#';
252 cal_link.id = DateTimeShortcuts.calendarLinkName + num;
246 cal_link.id = DateTimeShortcuts.calendarLinkName + num;
253 cal_link.addEventListener('click', function(e) {
247 cal_link.addEventListener('click', function(e) {
254 e.preventDefault();
248 e.preventDefault();
@@ -283,24 +277,24
283 // </div>
277 // </div>
284 // <p class="calendar-cancel"><a href="#">Cancel</a></p>
278 // <p class="calendar-cancel"><a href="#">Cancel</a></p>
285 // </div>
279 // </div>
286 var cal_box = document.createElement('div');
280 const cal_box = document.createElement('div');
287 cal_box.style.display = 'none';
281 cal_box.style.display = 'none';
288 cal_box.style.position = 'absolute';
282 cal_box.style.position = 'absolute';
289 cal_box.className = 'calendarbox module';
283 cal_box.className = 'calendarbox module';
290 cal_box.setAttribute('id', DateTimeShortcuts.calendarDivName1 + num);
284 cal_box.id = DateTimeShortcuts.calendarDivName1 + num;
291 document.body.appendChild(cal_box);
285 document.body.appendChild(cal_box);
292 cal_box.addEventListener('click', function(e) { e.stopPropagation(); });
286 cal_box.addEventListener('click', function(e) { e.stopPropagation(); });
293
287
294 // next-prev links
288 // next-prev links
295 var cal_nav = quickElement('div', cal_box);
289 const cal_nav = quickElement('div', cal_box);
296 var cal_nav_prev = quickElement('a', cal_nav, '<', 'href', '#');
290 const cal_nav_prev = quickElement('a', cal_nav, '<', 'href', '#');
297 cal_nav_prev.className = 'calendarnav-previous';
291 cal_nav_prev.className = 'calendarnav-previous';
298 cal_nav_prev.addEventListener('click', function(e) {
292 cal_nav_prev.addEventListener('click', function(e) {
299 e.preventDefault();
293 e.preventDefault();
300 DateTimeShortcuts.drawPrev(num);
294 DateTimeShortcuts.drawPrev(num);
301 });
295 });
302
296
303 var cal_nav_next = quickElement('a', cal_nav, '>', 'href', '#');
297 const cal_nav_next = quickElement('a', cal_nav, '>', 'href', '#');
304 cal_nav_next.className = 'calendarnav-next';
298 cal_nav_next.className = 'calendarnav-next';
305 cal_nav_next.addEventListener('click', function(e) {
299 cal_nav_next.addEventListener('click', function(e) {
306 e.preventDefault();
300 e.preventDefault();
@@ -308,15 +302,15
308 });
302 });
309
303
310 // main box
304 // main box
311 var cal_main = quickElement('div', cal_box, '', 'id', DateTimeShortcuts.calendarDivName2 + num);
305 const cal_main = quickElement('div', cal_box, '', 'id', DateTimeShortcuts.calendarDivName2 + num);
312 cal_main.className = 'calendar';
306 cal_main.className = 'calendar';
313 DateTimeShortcuts.calendars[num] = new Calendar(DateTimeShortcuts.calendarDivName2 + num, DateTimeShortcuts.handleCalendarCallback(num));
307 DateTimeShortcuts.calendars[num] = new Calendar(DateTimeShortcuts.calendarDivName2 + num, DateTimeShortcuts.handleCalendarCallback(num));
314 DateTimeShortcuts.calendars[num].drawCurrent();
308 DateTimeShortcuts.calendars[num].drawCurrent();
315
309
316 // calendar shortcuts
310 // calendar shortcuts
317 var shortcuts = quickElement('div', cal_box);
311 const shortcuts = quickElement('div', cal_box);
318 shortcuts.className = 'calendar-shortcuts';
312 shortcuts.className = 'calendar-shortcuts';
319 var day_link = quickElement('a', shortcuts, gettext('Yesterday'), 'href', '#');
313 let day_link = quickElement('a', shortcuts, gettext('Yesterday'), 'href', '#');
320 day_link.addEventListener('click', function(e) {
314 day_link.addEventListener('click', function(e) {
321 e.preventDefault();
315 e.preventDefault();
322 DateTimeShortcuts.handleCalendarQuickLink(num, -1);
316 DateTimeShortcuts.handleCalendarQuickLink(num, -1);
@@ -335,9 +329,9
335 });
329 });
336
330
337 // cancel bar
331 // cancel bar
338 var cancel_p = quickElement('p', cal_box);
332 const cancel_p = quickElement('p', cal_box);
339 cancel_p.className = 'calendar-cancel';
333 cancel_p.className = 'calendar-cancel';
340 var cancel_link = quickElement('a', cancel_p, gettext('Cancel'), 'href', '#');
334 const cancel_link = quickElement('a', cancel_p, gettext('Cancel'), 'href', '#');
341 cancel_link.addEventListener('click', function(e) {
335 cancel_link.addEventListener('click', function(e) {
342 e.preventDefault();
336 e.preventDefault();
343 DateTimeShortcuts.dismissCalendar(num);
337 DateTimeShortcuts.dismissCalendar(num);
@@ -351,18 +345,18
351 });
345 });
352 },
346 },
353 openCalendar: function(num) {
347 openCalendar: function(num) {
354 var cal_box = document.getElementById(DateTimeShortcuts.calendarDivName1 + num);
348 const cal_box = document.getElementById(DateTimeShortcuts.calendarDivName1 + num);
355 var cal_link = document.getElementById(DateTimeShortcuts.calendarLinkName + num);
349 const cal_link = document.getElementById(DateTimeShortcuts.calendarLinkName + num);
356 var inp = DateTimeShortcuts.calendarInputs[num];
350 const inp = DateTimeShortcuts.calendarInputs[num];
357
351
358 // Determine if the current value in the input has a valid date.
352 // Determine if the current value in the input has a valid date.
359 // If so, draw the calendar with that date's year and month.
353 // If so, draw the calendar with that date's year and month.
360 if (inp.value) {
354 if (inp.value) {
361 var format = get_format('DATE_INPUT_FORMATS')[0];
355 const format = get_format('DATE_INPUT_FORMATS')[0];
362 var selected = inp.value.strptime(format);
356 const selected = inp.value.strptime(format);
363 var year = selected.getUTCFullYear();
357 const year = selected.getUTCFullYear();
364 var month = selected.getUTCMonth() + 1;
358 const month = selected.getUTCMonth() + 1;
365 var re = /\d{4}/;
359 const re = /\d{4}/;
366 if (re.test(year.toString()) && month >= 1 && month <= 12) {
360 if (re.test(year.toString()) && month >= 1 && month <= 12) {
367 DateTimeShortcuts.calendars[num].drawDate(month, year, selected);
361 DateTimeShortcuts.calendars[num].drawDate(month, year, selected);
368 }
362 }
@@ -370,14 +364,12
370
364
371 // Recalculate the clockbox position
365 // Recalculate the clockbox position
372 // is it left-to-right or right-to-left layout ?
366 // is it left-to-right or right-to-left layout ?
373 if (getStyle(document.body, 'direction') !== 'rtl') {
367 if (window.getComputedStyle(document.body).direction !== 'rtl') {
374 cal_box.style.left = findPosX(cal_link) + 17 + 'px';
368 cal_box.style.left = findPosX(cal_link) + 17 + 'px';
375 }
369 }
376 else {
370 else {
377 // since style's width is in em, it'd be tough to calculate
371 // since style's width is in em, it'd be tough to calculate
378 // px value of it. let's use an estimated px for now
372 // px value of it. let's use an estimated px for now
379 // TODO: IE returns wrong value for findPosX when in rtl mode
380 // (it returns as it was left aligned), needs to be fixed.
381 cal_box.style.left = findPosX(cal_link) - 180 + 'px';
373 cal_box.style.left = findPosX(cal_link) - 180 + 'px';
382 }
374 }
383 cal_box.style.top = Math.max(0, findPosY(cal_link) - 75) + 'px';
375 cal_box.style.top = Math.max(0, findPosY(cal_link) - 75) + 'px';
@@ -396,13 +388,7
396 DateTimeShortcuts.calendars[num].drawNextMonth();
388 DateTimeShortcuts.calendars[num].drawNextMonth();
397 },
389 },
398 handleCalendarCallback: function(num) {
390 handleCalendarCallback: function(num) {
399 var format = get_format('DATE_INPUT_FORMATS')[0];
391 const format = get_format('DATE_INPUT_FORMATS')[0];
400 // the format needs to be escaped a little
401 format = format.replace('\\', '\\\\')
402 .replace('\r', '\\r')
403 .replace('\n', '\\n')
404 .replace('\t', '\\t')
405 .replace("'", "\\'");
406 return function(y, m, d) {
392 return function(y, m, d) {
407 DateTimeShortcuts.calendarInputs[num].value = new Date(y, m - 1, d).strftime(format);
393 DateTimeShortcuts.calendarInputs[num].value = new Date(y, m - 1, d).strftime(format);
408 DateTimeShortcuts.calendarInputs[num].focus();
394 DateTimeShortcuts.calendarInputs[num].focus();
@@ -410,7 +396,7
410 };
396 };
411 },
397 },
412 handleCalendarQuickLink: function(num, offset) {
398 handleCalendarQuickLink: function(num, offset) {
413 var d = DateTimeShortcuts.now();
399 const d = DateTimeShortcuts.now();
414 d.setDate(d.getDate() + offset);
400 d.setDate(d.getDate() + offset);
415 DateTimeShortcuts.calendarInputs[num].value = d.strftime(get_format('DATE_INPUT_FORMATS')[0]);
401 DateTimeShortcuts.calendarInputs[num].value = d.strftime(get_format('DATE_INPUT_FORMATS')[0]);
416 DateTimeShortcuts.calendarInputs[num].focus();
402 DateTimeShortcuts.calendarInputs[num].focus();
@@ -420,4 +406,4
420
406
421 window.addEventListener('load', DateTimeShortcuts.init);
407 window.addEventListener('load', DateTimeShortcuts.init);
422 window.DateTimeShortcuts = DateTimeShortcuts;
408 window.DateTimeShortcuts = DateTimeShortcuts;
423 })();
409 }
@@ -1,38 +1,48
1 /*global SelectBox, interpolate*/
1 /*global SelectBox, interpolate*/
2 // Handles related-objects functionality: lookup link for raw_id_fields
2 // Handles related-objects functionality: lookup link for raw_id_fields
3 // and Add Another links.
3 // and Add Another links.
4 'use strict';
5 {
6 const $ = django.jQuery;
7 let popupIndex = 0;
8 const relatedWindows = [];
9
10 function dismissChildPopups() {
11 relatedWindows.forEach(function(win) {
12 if(!win.closed) {
13 win.dismissChildPopups();
14 win.close();
15 }
16 });
17 }
18
19 function setPopupIndex() {
20 if(document.getElementsByName("_popup").length > 0) {
21 const index = window.name.lastIndexOf("__") + 2;
22 popupIndex = parseInt(window.name.substring(index));
23 } else {
24 popupIndex = 0;
25 }
26 }
4
27
5 (function($) {
28 function addPopupIndex(name) {
6 'use strict';
29 name = name + "__" + (popupIndex + 1);
7
30 return name;
8 // IE doesn't accept periods or dashes in the window name, but the element IDs
9 // we use to generate popup window names may contain them, therefore we map them
10 // to allowed characters in a reversible way so that we can locate the correct
11 // element when the popup window is dismissed.
12 function id_to_windowname(text) {
13 text = text.replace(/\./g, '__dot__');
14 text = text.replace(/\-/g, '__dash__');
15 return text;
16 }
31 }
17
32
18 function windowname_to_id(text) {
33 function removePopupIndex(name) {
19 text = text.replace(/__dot__/g, '.');
34 name = name.replace(new RegExp("__" + (popupIndex + 1) + "$"), '');
20 text = text.replace(/__dash__/g, '-');
35 return name;
21 return text;
22 }
36 }
23
37
24 function showAdminPopup(triggeringLink, name_regexp, add_popup) {
38 function showAdminPopup(triggeringLink, name_regexp, add_popup) {
25 var name = triggeringLink.id.replace(name_regexp, '');
39 const name = addPopupIndex(triggeringLink.id.replace(name_regexp, ''));
26 name = id_to_windowname(name);
40 const href = new URL(triggeringLink.href);
27 var href = triggeringLink.href;
28 if (add_popup) {
41 if (add_popup) {
29 if (href.indexOf('?') === -1) {
42 href.searchParams.set('_popup', 1);
30 href += '?_popup=1';
31 } else {
32 href += '&_popup=1';
33 }
34 }
43 }
35 var win = window.open(href, name, 'height=500,width=800,resizable=yes,scrollbars=yes');
44 const win = window.open(href, name, 'height=500,width=800,resizable=yes,scrollbars=yes');
45 relatedWindows.push(win);
36 win.focus();
46 win.focus();
37 return false;
47 return false;
38 }
48 }
@@ -42,13 +52,17
42 }
52 }
43
53
44 function dismissRelatedLookupPopup(win, chosenId) {
54 function dismissRelatedLookupPopup(win, chosenId) {
45 var name = windowname_to_id(win.name);
55 const name = removePopupIndex(win.name);
46 var elem = document.getElementById(name);
56 const elem = document.getElementById(name);
47 if (elem.className.indexOf('vManyToManyRawIdAdminField') !== -1 && elem.value) {
57 if (elem.classList.contains('vManyToManyRawIdAdminField') && elem.value) {
48 elem.value += ',' + chosenId;
58 elem.value += ',' + chosenId;
49 } else {
59 } else {
50 document.getElementById(name).value = chosenId;
60 document.getElementById(name).value = chosenId;
51 }
61 }
62 const index = relatedWindows.indexOf(win);
63 if (index > -1) {
64 relatedWindows.splice(index, 1);
65 }
52 win.close();
66 win.close();
53 }
67 }
54
68
@@ -57,15 +71,15
57 }
71 }
58
72
59 function updateRelatedObjectLinks(triggeringLink) {
73 function updateRelatedObjectLinks(triggeringLink) {
60 var $this = $(triggeringLink);
74 const $this = $(triggeringLink);
61 var siblings = $this.nextAll('.view-related, .change-related, .delete-related');
75 const siblings = $this.nextAll('.view-related, .change-related, .delete-related');
62 if (!siblings.length) {
76 if (!siblings.length) {
63 return;
77 return;
64 }
78 }
65 var value = $this.val();
79 const value = $this.val();
66 if (value) {
80 if (value) {
67 siblings.each(function() {
81 siblings.each(function() {
68 var elm = $(this);
82 const elm = $(this);
69 elm.attr('href', elm.attr('data-href-template').replace('__fk__', value));
83 elm.attr('href', elm.attr('data-href-template').replace('__fk__', value));
70 });
84 });
71 } else {
85 } else {
@@ -73,15 +87,46
73 }
87 }
74 }
88 }
75
89
90 function updateRelatedSelectsOptions(currentSelect, win, objId, newRepr, newId) {
91 // After create/edit a model from the options next to the current
92 // select (+ or :pencil:) update ForeignKey PK of the rest of selects
93 // in the page.
94
95 const path = win.location.pathname;
96 // Extract the model from the popup url '.../<model>/add/' or
97 // '.../<model>/<id>/change/' depending the action (add or change).
98 const modelName = path.split('/')[path.split('/').length - (objId ? 4 : 3)];
99 // Exclude autocomplete selects.
100 const selectsRelated = document.querySelectorAll(`[data-model-ref="${modelName}"] select:not(.admin-autocomplete)`);
101
102 selectsRelated.forEach(function(select) {
103 if (currentSelect === select) {
104 return;
105 }
106
107 let option = select.querySelector(`option[value="${objId}"]`);
108
109 if (!option) {
110 option = new Option(newRepr, newId);
111 select.options.add(option);
112 return;
113 }
114
115 option.textContent = newRepr;
116 option.value = newId;
117 });
118 }
119
76 function dismissAddRelatedObjectPopup(win, newId, newRepr) {
120 function dismissAddRelatedObjectPopup(win, newId, newRepr) {
77 var name = windowname_to_id(win.name);
121 const name = removePopupIndex(win.name);
78 var elem = document.getElementById(name);
122 const elem = document.getElementById(name);
79 if (elem) {
123 if (elem) {
80 var elemName = elem.nodeName.toUpperCase();
124 const elemName = elem.nodeName.toUpperCase();
81 if (elemName === 'SELECT') {
125 if (elemName === 'SELECT') {
82 elem.options[elem.options.length] = new Option(newRepr, newId, true, true);
126 elem.options[elem.options.length] = new Option(newRepr, newId, true, true);
127 updateRelatedSelectsOptions(elem, win, null, newRepr, newId);
83 } else if (elemName === 'INPUT') {
128 } else if (elemName === 'INPUT') {
84 if (elem.className.indexOf('vManyToManyRawIdAdminField') !== -1 && elem.value) {
129 if (elem.classList.contains('vManyToManyRawIdAdminField') && elem.value) {
85 elem.value += ',' + newId;
130 elem.value += ',' + newId;
86 } else {
131 } else {
87 elem.value = newId;
132 elem.value = newId;
@@ -90,49 +135,58
90 // Trigger a change event to update related links if required.
135 // Trigger a change event to update related links if required.
91 $(elem).trigger('change');
136 $(elem).trigger('change');
92 } else {
137 } else {
93 var toId = name + "_to";
138 const toId = name + "_to";
94 var o = new Option(newRepr, newId);
139 const o = new Option(newRepr, newId);
95 SelectBox.add_to_cache(toId, o);
140 SelectBox.add_to_cache(toId, o);
96 SelectBox.redisplay(toId);
141 SelectBox.redisplay(toId);
97 }
142 }
143 const index = relatedWindows.indexOf(win);
144 if (index > -1) {
145 relatedWindows.splice(index, 1);
146 }
98 win.close();
147 win.close();
99 }
148 }
100
149
101 function dismissChangeRelatedObjectPopup(win, objId, newRepr, newId) {
150 function dismissChangeRelatedObjectPopup(win, objId, newRepr, newId) {
102 var id = windowname_to_id(win.name).replace(/^edit_/, '');
151 const id = removePopupIndex(win.name.replace(/^edit_/, ''));
103 var selectsSelector = interpolate('#%s, #%s_from, #%s_to', [id, id, id]);
152 const selectsSelector = interpolate('#%s, #%s_from, #%s_to', [id, id, id]);
104 var selects = $(selectsSelector);
153 const selects = $(selectsSelector);
105 selects.find('option').each(function() {
154 selects.find('option').each(function() {
106 if (this.value === objId) {
155 if (this.value === objId) {
107 this.textContent = newRepr;
156 this.textContent = newRepr;
108 this.value = newId;
157 this.value = newId;
109 }
158 }
110 });
159 }).trigger('change');
160 updateRelatedSelectsOptions(selects[0], win, objId, newRepr, newId);
111 selects.next().find('.select2-selection__rendered').each(function() {
161 selects.next().find('.select2-selection__rendered').each(function() {
112 // The element can have a clear button as a child.
162 // The element can have a clear button as a child.
113 // Use the lastChild to modify only the displayed value.
163 // Use the lastChild to modify only the displayed value.
114 this.lastChild.textContent = newRepr;
164 this.lastChild.textContent = newRepr;
115 this.title = newRepr;
165 this.title = newRepr;
116 });
166 });
167 const index = relatedWindows.indexOf(win);
168 if (index > -1) {
169 relatedWindows.splice(index, 1);
170 }
117 win.close();
171 win.close();
118 }
172 }
119
173
120 function dismissDeleteRelatedObjectPopup(win, objId) {
174 function dismissDeleteRelatedObjectPopup(win, objId) {
121 var id = windowname_to_id(win.name).replace(/^delete_/, '');
175 const id = removePopupIndex(win.name.replace(/^delete_/, ''));
122 var selectsSelector = interpolate('#%s, #%s_from, #%s_to', [id, id, id]);
176 const selectsSelector = interpolate('#%s, #%s_from, #%s_to', [id, id, id]);
123 var selects = $(selectsSelector);
177 const selects = $(selectsSelector);
124 selects.find('option').each(function() {
178 selects.find('option').each(function() {
125 if (this.value === objId) {
179 if (this.value === objId) {
126 $(this).remove();
180 $(this).remove();
127 }
181 }
128 }).trigger('change');
182 }).trigger('change');
183 const index = relatedWindows.indexOf(win);
184 if (index > -1) {
185 relatedWindows.splice(index, 1);
186 }
129 win.close();
187 win.close();
130 }
188 }
131
189
132 // Global for testing purposes
133 window.id_to_windowname = id_to_windowname;
134 window.windowname_to_id = windowname_to_id;
135
136 window.showRelatedObjectLookupPopup = showRelatedObjectLookupPopup;
190 window.showRelatedObjectLookupPopup = showRelatedObjectLookupPopup;
137 window.dismissRelatedLookupPopup = dismissRelatedLookupPopup;
191 window.dismissRelatedLookupPopup = dismissRelatedLookupPopup;
138 window.showRelatedObjectPopup = showRelatedObjectPopup;
192 window.showRelatedObjectPopup = showRelatedObjectPopup;
@@ -140,20 +194,26
140 window.dismissAddRelatedObjectPopup = dismissAddRelatedObjectPopup;
194 window.dismissAddRelatedObjectPopup = dismissAddRelatedObjectPopup;
141 window.dismissChangeRelatedObjectPopup = dismissChangeRelatedObjectPopup;
195 window.dismissChangeRelatedObjectPopup = dismissChangeRelatedObjectPopup;
142 window.dismissDeleteRelatedObjectPopup = dismissDeleteRelatedObjectPopup;
196 window.dismissDeleteRelatedObjectPopup = dismissDeleteRelatedObjectPopup;
197 window.dismissChildPopups = dismissChildPopups;
143
198
144 // Kept for backward compatibility
199 // Kept for backward compatibility
145 window.showAddAnotherPopup = showRelatedObjectPopup;
200 window.showAddAnotherPopup = showRelatedObjectPopup;
146 window.dismissAddAnotherPopup = dismissAddRelatedObjectPopup;
201 window.dismissAddAnotherPopup = dismissAddRelatedObjectPopup;
147
202
203 window.addEventListener('unload', function(evt) {
204 window.dismissChildPopups();
205 });
206
148 $(document).ready(function() {
207 $(document).ready(function() {
208 setPopupIndex();
149 $("a[data-popup-opener]").on('click', function(event) {
209 $("a[data-popup-opener]").on('click', function(event) {
150 event.preventDefault();
210 event.preventDefault();
151 opener.dismissRelatedLookupPopup(window, $(this).data("popup-opener"));
211 opener.dismissRelatedLookupPopup(window, $(this).data("popup-opener"));
152 });
212 });
153 $('body').on('click', '.related-widget-wrapper-link', function(e) {
213 $('body').on('click', '.related-widget-wrapper-link[data-popup="yes"]', function(e) {
154 e.preventDefault();
214 e.preventDefault();
155 if (this.href) {
215 if (this.href) {
156 var event = $.Event('django:show-related', {href: this.href});
216 const event = $.Event('django:show-related', {href: this.href});
157 $(this).trigger(event);
217 $(this).trigger(event);
158 if (!event.isDefaultPrevented()) {
218 if (!event.isDefaultPrevented()) {
159 showRelatedObjectPopup(this);
219 showRelatedObjectPopup(this);
@@ -161,7 +221,7
161 }
221 }
162 });
222 });
163 $('body').on('change', '.related-widget-wrapper select', function(e) {
223 $('body').on('change', '.related-widget-wrapper select', function(e) {
164 var event = $.Event('django:update-related');
224 const event = $.Event('django:update-related');
165 $(this).trigger(event);
225 $(this).trigger(event);
166 if (!event.isDefaultPrevented()) {
226 if (!event.isDefaultPrevented()) {
167 updateRelatedObjectLinks(this);
227 updateRelatedObjectLinks(this);
@@ -170,12 +230,11
170 $('.related-widget-wrapper select').trigger('change');
230 $('.related-widget-wrapper select').trigger('change');
171 $('body').on('click', '.related-lookup', function(e) {
231 $('body').on('click', '.related-lookup', function(e) {
172 e.preventDefault();
232 e.preventDefault();
173 var event = $.Event('django:lookup-related');
233 const event = $.Event('django:lookup-related');
174 $(this).trigger(event);
234 $(this).trigger(event);
175 if (!event.isDefaultPrevented()) {
235 if (!event.isDefaultPrevented()) {
176 showRelatedObjectLookupPopup(this);
236 showRelatedObjectLookupPopup(this);
177 }
237 }
178 });
238 });
179 });
239 });
180
240 }
181 })(django.jQuery);
@@ -1,24 +1,22
1 (function($) {
1 'use strict';
2 'use strict';
2 {
3 var init = function($element, options) {
3 const $ = django.jQuery;
4 var settings = $.extend({
5 ajax: {
6 data: function(params) {
7 return {
8 term: params.term,
9 page: params.page
10 };
11 }
12 }
13 }, options);
14 $element.select2(settings);
15 };
16
4
17 $.fn.djangoAdminSelect2 = function(options) {
5 $.fn.djangoAdminSelect2 = function() {
18 var settings = $.extend({}, options);
19 $.each(this, function(i, element) {
6 $.each(this, function(i, element) {
20 var $element = $(element);
7 $(element).select2({
21 init($element, settings);
8 ajax: {
9 data: (params) => {
10 return {
11 term: params.term,
12 page: params.page,
13 app_label: element.dataset.appLabel,
14 model_name: element.dataset.modelName,
15 field_name: element.dataset.fieldName
16 };
17 }
18 }
19 });
22 });
20 });
23 return this;
21 return this;
24 };
22 };
@@ -29,9 +27,7
29 $('.admin-autocomplete').not('[name*=__prefix__]').djangoAdminSelect2();
27 $('.admin-autocomplete').not('[name*=__prefix__]').djangoAdminSelect2();
30 });
28 });
31
29
32 $(document).on('formset:added', (function() {
30 document.addEventListener('formset:added', (event) => {
33 return function(event, $newFormset) {
31 $(event.target).find('.admin-autocomplete').djangoAdminSelect2();
34 return $newFormset.find('.admin-autocomplete').djangoAdminSelect2();
32 });
35 };
33 }
36 })(this));
37 }(django.jQuery));
@@ -3,11 +3,10
3 calendar.js - Calendar functions by Adrian Holovaty
3 calendar.js - Calendar functions by Adrian Holovaty
4 depends on core.js for utility functions like removeChildren or quickElement
4 depends on core.js for utility functions like removeChildren or quickElement
5 */
5 */
6
6 'use strict';
7 (function() {
7 {
8 'use strict';
9 // CalendarNamespace -- Provides a collection of HTML calendar-related helper functions
8 // CalendarNamespace -- Provides a collection of HTML calendar-related helper functions
10 var CalendarNamespace = {
9 const CalendarNamespace = {
11 monthsOfYear: [
10 monthsOfYear: [
12 gettext('January'),
11 gettext('January'),
13 gettext('February'),
12 gettext('February'),
@@ -22,6 +21,20 depends on core.js for utility functions like removeChildren or quickElement
22 gettext('November'),
21 gettext('November'),
23 gettext('December')
22 gettext('December')
24 ],
23 ],
24 monthsOfYearAbbrev: [
25 pgettext('abbrev. month January', 'Jan'),
26 pgettext('abbrev. month February', 'Feb'),
27 pgettext('abbrev. month March', 'Mar'),
28 pgettext('abbrev. month April', 'Apr'),
29 pgettext('abbrev. month May', 'May'),
30 pgettext('abbrev. month June', 'Jun'),
31 pgettext('abbrev. month July', 'Jul'),
32 pgettext('abbrev. month August', 'Aug'),
33 pgettext('abbrev. month September', 'Sep'),
34 pgettext('abbrev. month October', 'Oct'),
35 pgettext('abbrev. month November', 'Nov'),
36 pgettext('abbrev. month December', 'Dec')
37 ],
25 daysOfWeek: [
38 daysOfWeek: [
26 pgettext('one letter Sunday', 'S'),
39 pgettext('one letter Sunday', 'S'),
27 pgettext('one letter Monday', 'M'),
40 pgettext('one letter Monday', 'M'),
@@ -36,7 +49,7 depends on core.js for utility functions like removeChildren or quickElement
36 return (((year % 4) === 0) && ((year % 100) !== 0 ) || ((year % 400) === 0));
49 return (((year % 4) === 0) && ((year % 100) !== 0 ) || ((year % 400) === 0));
37 },
50 },
38 getDaysInMonth: function(month, year) {
51 getDaysInMonth: function(month, year) {
39 var days;
52 let days;
40 if (month === 1 || month === 3 || month === 5 || month === 7 || month === 8 || month === 10 || month === 12) {
53 if (month === 1 || month === 3 || month === 5 || month === 7 || month === 8 || month === 10 || month === 12) {
41 days = 31;
54 days = 31;
42 }
55 }
@@ -52,11 +65,11 depends on core.js for utility functions like removeChildren or quickElement
52 return days;
65 return days;
53 },
66 },
54 draw: function(month, year, div_id, callback, selected) { // month = 1-12, year = 1-9999
67 draw: function(month, year, div_id, callback, selected) { // month = 1-12, year = 1-9999
55 var today = new Date();
68 const today = new Date();
56 var todayDay = today.getDate();
69 const todayDay = today.getDate();
57 var todayMonth = today.getMonth() + 1;
70 const todayMonth = today.getMonth() + 1;
58 var todayYear = today.getFullYear();
71 const todayYear = today.getFullYear();
59 var todayClass = '';
72 let todayClass = '';
60
73
61 // Use UTC functions here because the date field does not contain time
74 // Use UTC functions here because the date field does not contain time
62 // and using the UTC function variants prevent the local time offset
75 // and using the UTC function variants prevent the local time offset
@@ -69,33 +82,33 depends on core.js for utility functions like removeChildren or quickElement
69 //
82 //
70 // The day variable above will be 1 instead of 2 in, say, US Pacific time
83 // The day variable above will be 1 instead of 2 in, say, US Pacific time
71 // zone.
84 // zone.
72 var isSelectedMonth = false;
85 let isSelectedMonth = false;
73 if (typeof selected !== 'undefined') {
86 if (typeof selected !== 'undefined') {
74 isSelectedMonth = (selected.getUTCFullYear() === year && (selected.getUTCMonth() + 1) === month);
87 isSelectedMonth = (selected.getUTCFullYear() === year && (selected.getUTCMonth() + 1) === month);
75 }
88 }
76
89
77 month = parseInt(month);
90 month = parseInt(month);
78 year = parseInt(year);
91 year = parseInt(year);
79 var calDiv = document.getElementById(div_id);
92 const calDiv = document.getElementById(div_id);
80 removeChildren(calDiv);
93 removeChildren(calDiv);
81 var calTable = document.createElement('table');
94 const calTable = document.createElement('table');
82 quickElement('caption', calTable, CalendarNamespace.monthsOfYear[month - 1] + ' ' + year);
95 quickElement('caption', calTable, CalendarNamespace.monthsOfYear[month - 1] + ' ' + year);
83 var tableBody = quickElement('tbody', calTable);
96 const tableBody = quickElement('tbody', calTable);
84
97
85 // Draw days-of-week header
98 // Draw days-of-week header
86 var tableRow = quickElement('tr', tableBody);
99 let tableRow = quickElement('tr', tableBody);
87 for (var i = 0; i < 7; i++) {
100 for (let i = 0; i < 7; i++) {
88 quickElement('th', tableRow, CalendarNamespace.daysOfWeek[(i + CalendarNamespace.firstDayOfWeek) % 7]);
101 quickElement('th', tableRow, CalendarNamespace.daysOfWeek[(i + CalendarNamespace.firstDayOfWeek) % 7]);
89 }
102 }
90
103
91 var startingPos = new Date(year, month - 1, 1 - CalendarNamespace.firstDayOfWeek).getDay();
104 const startingPos = new Date(year, month - 1, 1 - CalendarNamespace.firstDayOfWeek).getDay();
92 var days = CalendarNamespace.getDaysInMonth(month, year);
105 const days = CalendarNamespace.getDaysInMonth(month, year);
93
106
94 var nonDayCell;
107 let nonDayCell;
95
108
96 // Draw blanks before first of month
109 // Draw blanks before first of month
97 tableRow = quickElement('tr', tableBody);
110 tableRow = quickElement('tr', tableBody);
98 for (i = 0; i < startingPos; i++) {
111 for (let i = 0; i < startingPos; i++) {
99 nonDayCell = quickElement('td', tableRow, ' ');
112 nonDayCell = quickElement('td', tableRow, ' ');
100 nonDayCell.className = "nonday";
113 nonDayCell.className = "nonday";
101 }
114 }
@@ -109,8 +122,8 depends on core.js for utility functions like removeChildren or quickElement
109 }
122 }
110
123
111 // Draw days of month
124 // Draw days of month
112 var currentDay = 1;
125 let currentDay = 1;
113 for (i = startingPos; currentDay <= days; i++) {
126 for (let i = startingPos; currentDay <= days; i++) {
114 if (i % 7 === 0 && currentDay !== 1) {
127 if (i % 7 === 0 && currentDay !== 1) {
115 tableRow = quickElement('tr', tableBody);
128 tableRow = quickElement('tr', tableBody);
116 }
129 }
@@ -128,8 +141,8 depends on core.js for utility functions like removeChildren or quickElement
128 todayClass += "selected";
141 todayClass += "selected";
129 }
142 }
130
143
131 var cell = quickElement('td', tableRow, '', 'class', todayClass);
144 const cell = quickElement('td', tableRow, '', 'class', todayClass);
132 var link = quickElement('a', cell, currentDay, 'href', '#');
145 const link = quickElement('a', cell, currentDay, 'href', '#');
133 link.addEventListener('click', calendarMonth(year, month));
146 link.addEventListener('click', calendarMonth(year, month));
134 currentDay++;
147 currentDay++;
135 }
148 }
@@ -205,4 +218,4 depends on core.js for utility functions like removeChildren or quickElement
205 };
218 };
206 window.Calendar = Calendar;
219 window.Calendar = Calendar;
207 window.CalendarNamespace = CalendarNamespace;
220 window.CalendarNamespace = CalendarNamespace;
208 })();
221 }
@@ -1,13 +1,29
1 (function($) {
1 'use strict';
2 'use strict';
2 {
3 $(function() {
3 // Call function fn when the DOM is loaded and ready. If it is already
4 $('.cancel-link').on('click', function(e) {
4 // loaded, call the function now.
5 e.preventDefault();
5 // http://youmightnotneedjquery.com/#ready
6 if (window.location.search.indexOf('&_popup=1') === -1) {
6 function ready(fn) {
7 window.history.back(); // Go back if not a popup.
7 if (document.readyState !== 'loading') {
8 fn();
9 } else {
10 document.addEventListener('DOMContentLoaded', fn);
11 }
12 }
13
14 ready(function() {
15 function handleClick(event) {
16 event.preventDefault();
17 const params = new URLSearchParams(window.location.search);
18 if (params.has('_popup')) {
19 window.close(); // Close the popup.
8 } else {
20 } else {
9 window.close(); // Otherwise, close the popup.
21 window.history.back(); // Otherwise, go back.
10 }
22 }
23 }
24
25 document.querySelectorAll('.cancel-link').forEach(function(el) {
26 el.addEventListener('click', handleClick);
11 });
27 });
12 });
28 });
13 })(django.jQuery);
29 }
@@ -1,20 +1,16
1 /*global showAddAnotherPopup, showRelatedObjectLookupPopup showRelatedObjectPopup updateRelatedObjectLinks*/
1 'use strict';
2
2 {
3 (function($) {
3 const inputTags = ['BUTTON', 'INPUT', 'SELECT', 'TEXTAREA'];
4 'use strict';
4 const modelName = document.getElementById('django-admin-form-add-constants').dataset.modelName;
5 $(document).ready(function() {
5 if (modelName) {
6 var modelName = $('#django-admin-form-add-constants').data('modelName');
6 const form = document.getElementById(modelName + '_form');
7 $('body').on('click', '.add-another', function(e) {
7 for (const element of form.elements) {
8 e.preventDefault();
8 // HTMLElement.offsetParent returns null when the element is not
9 var event = $.Event('django:add-another-related');
9 // rendered.
10 $(this).trigger(event);
10 if (inputTags.includes(element.tagName) && !element.disabled && element.offsetParent) {
11 if (!event.isDefaultPrevented()) {
11 element.focus();
12 showAddAnotherPopup(this);
12 break;
13 }
13 }
14 });
15
16 if (modelName) {
17 $('form#' + modelName + '_form :input:visible:enabled:first').focus();
18 }
14 }
19 });
15 }
20 })(django.jQuery);
16 }
@@ -1,52 +1,43
1 /*global gettext*/
1 /*global gettext*/
2 (function() {
2 'use strict';
3 'use strict';
3 {
4 var closestElem = function(elem, tagName) {
5 if (elem.nodeName === tagName.toUpperCase()) {
6 return elem;
7 }
8 if (elem.parentNode.nodeName === 'BODY') {
9 return null;
10 }
11 return elem.parentNode && closestElem(elem.parentNode, tagName);
12 };
13
14 window.addEventListener('load', function() {
4 window.addEventListener('load', function() {
15 // Add anchor tag for Show/Hide link
5 // Add anchor tag for Show/Hide link
16 var fieldsets = document.querySelectorAll('fieldset.collapse');
6 const fieldsets = document.querySelectorAll('fieldset.collapse');
17 for (var i = 0; i < fieldsets.length; i++) {
7 for (const [i, elem] of fieldsets.entries()) {
18 var elem = fieldsets[i];
19 // Don't hide if fields in this fieldset have errors
8 // Don't hide if fields in this fieldset have errors
20 if (elem.querySelectorAll('div.errors').length === 0) {
9 if (elem.querySelectorAll('div.errors, ul.errorlist').length === 0) {
21 elem.classList.add('collapsed');
10 elem.classList.add('collapsed');
22 var h2 = elem.querySelector('h2');
11 const h2 = elem.querySelector('h2');
23 var link = document.createElement('a');
12 const link = document.createElement('a');
24 link.setAttribute('id', 'fieldsetcollapser' + i);
13 link.id = 'fieldsetcollapser' + i;
25 link.setAttribute('class', 'collapse-toggle');
14 link.className = 'collapse-toggle';
26 link.setAttribute('href', '#');
15 link.href = '#';
27 link.textContent = gettext('Show');
16 link.textContent = gettext('Show');
28 h2.appendChild(document.createTextNode(' ('));
17 h2.appendChild(document.createTextNode(' ('));
29 h2.appendChild(link);
18 h2.appendChild(link);
30 h2.appendChild(document.createTextNode(')'));
19 h2.appendChild(document.createTextNode(')'));
31 }
20 }
32 }
21 }
33 // Add toggle to anchor tag
22 // Add toggle to hide/show anchor tag
34 var toggles = document.querySelectorAll('fieldset.collapse a.collapse-toggle');
23 const toggleFunc = function(ev) {
35 var toggleFunc = function(ev) {
24 if (ev.target.matches('.collapse-toggle')) {
36 ev.preventDefault();
25 ev.preventDefault();
37 var fieldset = closestElem(this, 'fieldset');
26 ev.stopPropagation();
38 if (fieldset.classList.contains('collapsed')) {
27 const fieldset = ev.target.closest('fieldset');
39 // Show
28 if (fieldset.classList.contains('collapsed')) {
40 this.textContent = gettext('Hide');
29 // Show
41 fieldset.classList.remove('collapsed');
30 ev.target.textContent = gettext('Hide');
42 } else {
31 fieldset.classList.remove('collapsed');
43 // Hide
32 } else {
44 this.textContent = gettext('Show');
33 // Hide
45 fieldset.classList.add('collapsed');
34 ev.target.textContent = gettext('Show');
35 fieldset.classList.add('collapsed');
36 }
46 }
37 }
47 };
38 };
48 for (i = 0; i < toggles.length; i++) {
39 document.querySelectorAll('fieldset.module').forEach(function(el) {
49 toggles[i].addEventListener('click', toggleFunc);
40 el.addEventListener('click', toggleFunc);
50 }
41 });
51 });
42 });
52 })();
43 }
@@ -1,19 +1,15
1 // Core javascript helper functions
1 // Core JavaScript helper functions
2
2 'use strict';
3 // basic browser identification & version
4 var isOpera = (navigator.userAgent.indexOf("Opera") >= 0) && parseFloat(navigator.appVersion);
5 var isIE = ((document.all) && (!isOpera)) && parseFloat(navigator.appVersion.split("MSIE ")[1].split(";")[0]);
6
3
7 // quickElement(tagType, parentReference [, textInChildNode, attribute, attributeValue ...]);
4 // quickElement(tagType, parentReference [, textInChildNode, attribute, attributeValue ...]);
8 function quickElement() {
5 function quickElement() {
9 'use strict';
6 const obj = document.createElement(arguments[0]);
10 var obj = document.createElement(arguments[0]);
11 if (arguments[2]) {
7 if (arguments[2]) {
12 var textNode = document.createTextNode(arguments[2]);
8 const textNode = document.createTextNode(arguments[2]);
13 obj.appendChild(textNode);
9 obj.appendChild(textNode);
14 }
10 }
15 var len = arguments.length;
11 const len = arguments.length;
16 for (var i = 3; i < len; i += 2) {
12 for (let i = 3; i < len; i += 2) {
17 obj.setAttribute(arguments[i], arguments[i + 1]);
13 obj.setAttribute(arguments[i], arguments[i + 1]);
18 }
14 }
19 arguments[1].appendChild(obj);
15 arguments[1].appendChild(obj);
@@ -22,7 +18,6 function quickElement() {
22
18
23 // "a" is reference to an object
19 // "a" is reference to an object
24 function removeChildren(a) {
20 function removeChildren(a) {
25 'use strict';
26 while (a.hasChildNodes()) {
21 while (a.hasChildNodes()) {
27 a.removeChild(a.lastChild);
22 a.removeChild(a.lastChild);
28 }
23 }
@@ -33,16 +28,11 function removeChildren(a) {
33 // See https://www.quirksmode.org/js/findpos.html
28 // See https://www.quirksmode.org/js/findpos.html
34 // ----------------------------------------------------------------------------
29 // ----------------------------------------------------------------------------
35 function findPosX(obj) {
30 function findPosX(obj) {
36 'use strict';
31 let curleft = 0;
37 var curleft = 0;
38 if (obj.offsetParent) {
32 if (obj.offsetParent) {
39 while (obj.offsetParent) {
33 while (obj.offsetParent) {
40 curleft += obj.offsetLeft - ((isOpera) ? 0 : obj.scrollLeft);
41 obj = obj.offsetParent;
42 }
43 // IE offsetParent does not include the top-level
44 if (isIE && obj.parentElement) {
45 curleft += obj.offsetLeft - obj.scrollLeft;
34 curleft += obj.offsetLeft - obj.scrollLeft;
35 obj = obj.offsetParent;
46 }
36 }
47 } else if (obj.x) {
37 } else if (obj.x) {
48 curleft += obj.x;
38 curleft += obj.x;
@@ -51,16 +41,11 function findPosX(obj) {
51 }
41 }
52
42
53 function findPosY(obj) {
43 function findPosY(obj) {
54 'use strict';
44 let curtop = 0;
55 var curtop = 0;
56 if (obj.offsetParent) {
45 if (obj.offsetParent) {
57 while (obj.offsetParent) {
46 while (obj.offsetParent) {
58 curtop += obj.offsetTop - ((isOpera) ? 0 : obj.scrollTop);
59 obj = obj.offsetParent;
60 }
61 // IE offsetParent does not include the top-level
62 if (isIE && obj.parentElement) {
63 curtop += obj.offsetTop - obj.scrollTop;
47 curtop += obj.offsetTop - obj.scrollTop;
48 obj = obj.offsetParent;
64 }
49 }
65 } else if (obj.y) {
50 } else if (obj.y) {
66 curtop += obj.y;
51 curtop += obj.y;
@@ -71,16 +56,9 function findPosY(obj) {
71 //-----------------------------------------------------------------------------
56 //-----------------------------------------------------------------------------
72 // Date object extensions
57 // Date object extensions
73 // ----------------------------------------------------------------------------
58 // ----------------------------------------------------------------------------
74 (function() {
59 {
75 'use strict';
76 Date.prototype.getTwelveHours = function() {
60 Date.prototype.getTwelveHours = function() {
77 var hours = this.getHours();
61 return this.getHours() % 12 || 12;
78 if (hours === 0) {
79 return 12;
80 }
81 else {
82 return hours <= 12 ? hours : hours - 12;
83 }
84 };
62 };
85
63
86 Date.prototype.getTwoDigitMonth = function() {
64 Date.prototype.getTwoDigitMonth = function() {
@@ -107,12 +85,10 function findPosY(obj) {
107 return (this.getSeconds() < 10) ? '0' + this.getSeconds() : this.getSeconds();
85 return (this.getSeconds() < 10) ? '0' + this.getSeconds() : this.getSeconds();
108 };
86 };
109
87
110 Date.prototype.getHourMinute = function() {
88 Date.prototype.getAbbrevMonthName = function() {
111 return this.getTwoDigitHour() + ':' + this.getTwoDigitMinute();
89 return typeof window.CalendarNamespace === "undefined"
112 };
90 ? this.getTwoDigitMonth()
113
91 : window.CalendarNamespace.monthsOfYearAbbrev[this.getMonth()];
114 Date.prototype.getHourMinuteSecond = function() {
115 return this.getTwoDigitHour() + ':' + this.getTwoDigitMinute() + ':' + this.getTwoDigitSecond();
116 };
92 };
117
93
118 Date.prototype.getFullMonthName = function() {
94 Date.prototype.getFullMonthName = function() {
@@ -122,7 +98,8 function findPosY(obj) {
122 };
98 };
123
99
124 Date.prototype.strftime = function(format) {
100 Date.prototype.strftime = function(format) {
125 var fields = {
101 const fields = {
102 b: this.getAbbrevMonthName(),
126 B: this.getFullMonthName(),
103 B: this.getFullMonthName(),
127 c: this.toString(),
104 c: this.toString(),
128 d: this.getTwoDigitDate(),
105 d: this.getTwoDigitDate(),
@@ -139,7 +116,7 function findPosY(obj) {
139 Y: '' + this.getFullYear(),
116 Y: '' + this.getFullYear(),
140 '%': '%'
117 '%': '%'
141 };
118 };
142 var result = '', i = 0;
119 let result = '', i = 0;
143 while (i < format.length) {
120 while (i < format.length) {
144 if (format.charAt(i) === '%') {
121 if (format.charAt(i) === '%') {
145 result = result + fields[format.charAt(i + 1)];
122 result = result + fields[format.charAt(i + 1)];
@@ -153,36 +130,35 function findPosY(obj) {
153 return result;
130 return result;
154 };
131 };
155
132
156 // ----------------------------------------------------------------------------
133 // ----------------------------------------------------------------------------
157 // String object extensions
134 // String object extensions
158 // ----------------------------------------------------------------------------
135 // ----------------------------------------------------------------------------
159 String.prototype.pad_left = function(pad_length, pad_string) {
160 var new_string = this;
161 for (var i = 0; new_string.length < pad_length; i++) {
162 new_string = pad_string + new_string;
163 }
164 return new_string;
165 };
166
167 String.prototype.strptime = function(format) {
136 String.prototype.strptime = function(format) {
168 var split_format = format.split(/[.\-/]/);
137 const split_format = format.split(/[.\-/]/);
169 var date = this.split(/[.\-/]/);
138 const date = this.split(/[.\-/]/);
170 var i = 0;
139 let i = 0;
171 var day, month, year;
140 let day, month, year;
172 while (i < split_format.length) {
141 while (i < split_format.length) {
173 switch (split_format[i]) {
142 switch (split_format[i]) {
174 case "%d":
143 case "%d":
175 day = date[i];
144 day = date[i];
176 break;
145 break;
177 case "%m":
146 case "%m":
178 month = date[i] - 1;
147 month = date[i] - 1;
179 break;
148 break;
180 case "%Y":
149 case "%Y":
150 year = date[i];
151 break;
152 case "%y":
153 // A %y value in the range of [00, 68] is in the current
154 // century, while [69, 99] is in the previous century,
155 // according to the Open Group Specification.
156 if (parseInt(date[i], 10) >= 69) {
181 year = date[i];
157 year = date[i];
182 break;
158 } else {
183 case "%y":
159 year = (new Date(Date.UTC(date[i], 0))).getUTCFullYear() + 100;
184 year = date[i];
160 }
185 break;
161 break;
186 }
162 }
187 ++i;
163 ++i;
188 }
164 }
@@ -191,22 +167,4 function findPosY(obj) {
191 // date extraction.
167 // date extraction.
192 return new Date(Date.UTC(year, month, day));
168 return new Date(Date.UTC(year, month, day));
193 };
169 };
194
195 })();
196 // ----------------------------------------------------------------------------
197 // Get the computed style for and element
198 // ----------------------------------------------------------------------------
199 function getStyle(oElm, strCssRule) {
200 'use strict';
201 var strValue = "";
202 if(document.defaultView && document.defaultView.getComputedStyle) {
203 strValue = document.defaultView.getComputedStyle(oElm, "").getPropertyValue(strCssRule);
204 }
205 else if(oElm.currentStyle) {
206 strCssRule = strCssRule.replace(/\-(\w)/g, function(strMatch, p1) {
207 return p1.toUpperCase();
208 });
209 strValue = oElm.currentStyle[strCssRule];
210 }
211 return strValue;
212 }
170 }
@@ -15,15 +15,16
15 * Licensed under the New BSD License
15 * Licensed under the New BSD License
16 * See: https://opensource.org/licenses/bsd-license.php
16 * See: https://opensource.org/licenses/bsd-license.php
17 */
17 */
18 (function($) {
18 'use strict';
19 'use strict';
19 {
20 const $ = django.jQuery;
20 $.fn.formset = function(opts) {
21 $.fn.formset = function(opts) {
21 var options = $.extend({}, $.fn.formset.defaults, opts);
22 const options = $.extend({}, $.fn.formset.defaults, opts);
22 var $this = $(this);
23 const $this = $(this);
23 var $parent = $this.parent();
24 const $parent = $this.parent();
24 var updateElementIndex = function(el, prefix, ndx) {
25 const updateElementIndex = function(el, prefix, ndx) {
25 var id_regex = new RegExp("(" + prefix + "-(\\d+|__prefix__))");
26 const id_regex = new RegExp("(" + prefix + "-(\\d+|__prefix__))");
26 var replacement = prefix + "-" + ndx;
27 const replacement = prefix + "-" + ndx;
27 if ($(el).prop("for")) {
28 if ($(el).prop("for")) {
28 $(el).prop("for", $(el).prop("for").replace(id_regex, replacement));
29 $(el).prop("for", $(el).prop("for").replace(id_regex, replacement));
29 }
30 }
@@ -34,22 +35,21
34 el.name = el.name.replace(id_regex, replacement);
35 el.name = el.name.replace(id_regex, replacement);
35 }
36 }
36 };
37 };
37 var totalForms = $("#id_" + options.prefix + "-TOTAL_FORMS").prop("autocomplete", "off");
38 const totalForms = $("#id_" + options.prefix + "-TOTAL_FORMS").prop("autocomplete", "off");
38 var nextIndex = parseInt(totalForms.val(), 10);
39 let nextIndex = parseInt(totalForms.val(), 10);
39 var maxForms = $("#id_" + options.prefix + "-MAX_NUM_FORMS").prop("autocomplete", "off");
40 const maxForms = $("#id_" + options.prefix + "-MAX_NUM_FORMS").prop("autocomplete", "off");
40 // only show the add button if we are allowed to add more items,
41 const minForms = $("#id_" + options.prefix + "-MIN_NUM_FORMS").prop("autocomplete", "off");
41 // note that max_num = None translates to a blank string.
42 let addButton;
42 var showAddButton = maxForms.val() === '' || (maxForms.val() - totalForms.val()) > 0;
43
43 $this.each(function(i) {
44 /**
44 $(this).not("." + options.emptyCssClass).addClass(options.formCssClass);
45 * The "Add another MyModel" button below the inline forms.
45 });
46 */
46 if ($this.length && showAddButton) {
47 const addInlineAddButton = function() {
47 var addButton = options.addButton;
48 if (addButton === null) {
48 if (addButton === null) {
49 if ($this.prop("tagName") === "TR") {
49 if ($this.prop("tagName") === "TR") {
50 // If forms are laid out as table rows, insert the
50 // If forms are laid out as table rows, insert the
51 // "add" button in a new table row:
51 // "add" button in a new table row:
52 var numCols = this.eq(-1).children().length;
52 const numCols = $this.eq(-1).children().length;
53 $parent.append('<tr class="' + options.addCssClass + '"><td colspan="' + numCols + '"><a href="#">' + options.addText + "</a></tr>");
53 $parent.append('<tr class="' + options.addCssClass + '"><td colspan="' + numCols + '"><a href="#">' + options.addText + "</a></tr>");
54 addButton = $parent.find("tr:last a");
54 addButton = $parent.find("tr:last a");
55 } else {
55 } else {
@@ -58,102 +58,163
58 addButton = $this.filter(":last").next().find("a");
58 addButton = $this.filter(":last").next().find("a");
59 }
59 }
60 }
60 }
61 addButton.on('click', function(e) {
61 addButton.on('click', addInlineClickHandler);
62 e.preventDefault();
62 };
63 var template = $("#" + options.prefix + "-empty");
63
64 var row = template.clone(true);
64 const addInlineClickHandler = function(e) {
65 row.removeClass(options.emptyCssClass)
65 e.preventDefault();
66 const template = $("#" + options.prefix + "-empty");
67 const row = template.clone(true);
68 row.removeClass(options.emptyCssClass)
66 .addClass(options.formCssClass)
69 .addClass(options.formCssClass)
67 .attr("id", options.prefix + "-" + nextIndex);
70 .attr("id", options.prefix + "-" + nextIndex);
68 if (row.is("tr")) {
71 addInlineDeleteButton(row);
69 // If the forms are laid out in table rows, insert
72 row.find("*").each(function() {
70 // the remove button into the last table cell:
73 updateElementIndex(this, options.prefix, totalForms.val());
71 row.children(":last").append('<div><a class="' + options.deleteCssClass + '" href="#">' + options.deleteText + "</a></div>");
74 });
72 } else if (row.is("ul") || row.is("ol")) {
75 // Insert the new form when it has been fully edited.
73 // If they're laid out as an ordered/unordered list,
76 row.insertBefore($(template));
74 // insert an <li> after the last list item:
77 // Update number of total forms.
75 row.append('<li><a class="' + options.deleteCssClass + '" href="#">' + options.deleteText + "</a></li>");
78 $(totalForms).val(parseInt(totalForms.val(), 10) + 1);
76 } else {
79 nextIndex += 1;
77 // Otherwise, just insert the remove button as the
80 // Hide the add button if there's a limit and it's been reached.
78 // last child element of the form's container:
81 if ((maxForms.val() !== '') && (maxForms.val() - totalForms.val()) <= 0) {
79 row.children(":first").append('<span><a class="' + options.deleteCssClass + '" href="#">' + options.deleteText + "</a></span>");
82 addButton.parent().hide();
80 }
83 }
81 row.find("*").each(function() {
84 // Show the remove buttons if there are more than min_num.
82 updateElementIndex(this, options.prefix, totalForms.val());
85 toggleDeleteButtonVisibility(row.closest('.inline-group'));
83 });
86
84 // Insert the new form when it has been fully edited
87 // Pass the new form to the post-add callback, if provided.
85 row.insertBefore($(template));
88 if (options.added) {
86 // Update number of total forms
89 options.added(row);
87 $(totalForms).val(parseInt(totalForms.val(), 10) + 1);
90 }
88 nextIndex += 1;
91 row.get(0).dispatchEvent(new CustomEvent("formset:added", {
89 // Hide add button in case we've hit the max, except we want to add infinitely
92 bubbles: true,
90 if ((maxForms.val() !== '') && (maxForms.val() - totalForms.val()) <= 0) {
93 detail: {
91 addButton.parent().hide();
94 formsetName: options.prefix
92 }
95 }
93 // The delete button of each row triggers a bunch of other things
96 }));
94 row.find("a." + options.deleteCssClass).on('click', function(e1) {
97 };
95 e1.preventDefault();
98
96 // Remove the parent form containing this button:
99 /**
97 row.remove();
100 * The "X" button that is part of every unsaved inline.
98 nextIndex -= 1;
101 * (When saved, it is replaced with a "Delete" checkbox.)
99 // If a post-delete callback was provided, call it with the deleted form:
102 */
100 if (options.removed) {
103 const addInlineDeleteButton = function(row) {
101 options.removed(row);
104 if (row.is("tr")) {
102 }
105 // If the forms are laid out in table rows, insert
103 $(document).trigger('formset:removed', [row, options.prefix]);
106 // the remove button into the last table cell:
104 // Update the TOTAL_FORMS form count.
107 row.children(":last").append('<div><a class="' + options.deleteCssClass + '" href="#">' + options.deleteText + "</a></div>");
105 var forms = $("." + options.formCssClass);
108 } else if (row.is("ul") || row.is("ol")) {
106 $("#id_" + options.prefix + "-TOTAL_FORMS").val(forms.length);
109 // If they're laid out as an ordered/unordered list,
107 // Show add button again once we drop below max
110 // insert an <li> after the last list item:
108 if ((maxForms.val() === '') || (maxForms.val() - forms.length) > 0) {
111 row.append('<li><a class="' + options.deleteCssClass + '" href="#">' + options.deleteText + "</a></li>");
109 addButton.parent().show();
112 } else {
110 }
113 // Otherwise, just insert the remove button as the
111 // Also, update names and ids for all remaining form controls
114 // last child element of the form's container:
112 // so they remain in sequence:
115 row.children(":first").append('<span><a class="' + options.deleteCssClass + '" href="#">' + options.deleteText + "</a></span>");
113 var i, formCount;
116 }
114 var updateElementCallback = function() {
117 // Add delete handler for each row.
115 updateElementIndex(this, options.prefix, i);
118 row.find("a." + options.deleteCssClass).on('click', inlineDeleteHandler.bind(this));
116 };
119 };
117 for (i = 0, formCount = forms.length; i < formCount; i++) {
120
118 updateElementIndex($(forms).get(i), options.prefix, i);
121 const inlineDeleteHandler = function(e1) {
119 $(forms.get(i)).find("*").each(updateElementCallback);
122 e1.preventDefault();
120 }
123 const deleteButton = $(e1.target);
121 });
124 const row = deleteButton.closest('.' + options.formCssClass);
122 // If a post-add callback was supplied, call it with the added form:
125 const inlineGroup = row.closest('.inline-group');
123 if (options.added) {
126 // Remove the parent form containing this button,
124 options.added(row);
127 // and also remove the relevant row with non-field errors:
128 const prevRow = row.prev();
129 if (prevRow.length && prevRow.hasClass('row-form-errors')) {
130 prevRow.remove();
131 }
132 row.remove();
133 nextIndex -= 1;
134 // Pass the deleted form to the post-delete callback, if provided.
135 if (options.removed) {
136 options.removed(row);
137 }
138 document.dispatchEvent(new CustomEvent("formset:removed", {
139 detail: {
140 formsetName: options.prefix
125 }
141 }
126 $(document).trigger('formset:added', [row, options.prefix]);
142 }));
127 });
143 // Update the TOTAL_FORMS form count.
144 const forms = $("." + options.formCssClass);
145 $("#id_" + options.prefix + "-TOTAL_FORMS").val(forms.length);
146 // Show add button again once below maximum number.
147 if ((maxForms.val() === '') || (maxForms.val() - forms.length) > 0) {
148 addButton.parent().show();
149 }
150 // Hide the remove buttons if at min_num.
151 toggleDeleteButtonVisibility(inlineGroup);
152 // Also, update names and ids for all remaining form controls so
153 // they remain in sequence:
154 let i, formCount;
155 const updateElementCallback = function() {
156 updateElementIndex(this, options.prefix, i);
157 };
158 for (i = 0, formCount = forms.length; i < formCount; i++) {
159 updateElementIndex($(forms).get(i), options.prefix, i);
160 $(forms.get(i)).find("*").each(updateElementCallback);
161 }
162 };
163
164 const toggleDeleteButtonVisibility = function(inlineGroup) {
165 if ((minForms.val() !== '') && (minForms.val() - totalForms.val()) >= 0) {
166 inlineGroup.find('.inline-deletelink').hide();
167 } else {
168 inlineGroup.find('.inline-deletelink').show();
169 }
170 };
171
172 $this.each(function(i) {
173 $(this).not("." + options.emptyCssClass).addClass(options.formCssClass);
174 });
175
176 // Create the delete buttons for all unsaved inlines:
177 $this.filter('.' + options.formCssClass + ':not(.has_original):not(.' + options.emptyCssClass + ')').each(function() {
178 addInlineDeleteButton($(this));
179 });
180 toggleDeleteButtonVisibility($this);
181
182 // Create the add button, initially hidden.
183 addButton = options.addButton;
184 addInlineAddButton();
185
186 // Show the add button if allowed to add more items.
187 // Note that max_num = None translates to a blank string.
188 const showAddButton = maxForms.val() === '' || (maxForms.val() - totalForms.val()) > 0;
189 if ($this.length && showAddButton) {
190 addButton.parent().show();
191 } else {
192 addButton.parent().hide();
128 }
193 }
194
129 return this;
195 return this;
130 };
196 };
131
197
132 /* Setup plugin defaults */
198 /* Setup plugin defaults */
133 $.fn.formset.defaults = {
199 $.fn.formset.defaults = {
134 prefix: "form", // The form prefix for your django formset
200 prefix: "form", // The form prefix for your django formset
135 addText: "add another", // Text for the add link
201 addText: "add another", // Text for the add link
136 deleteText: "remove", // Text for the delete link
202 deleteText: "remove", // Text for the delete link
137 addCssClass: "add-row", // CSS class applied to the add link
203 addCssClass: "add-row", // CSS class applied to the add link
138 deleteCssClass: "delete-row", // CSS class applied to the delete link
204 deleteCssClass: "delete-row", // CSS class applied to the delete link
139 emptyCssClass: "empty-row", // CSS class applied to the empty row
205 emptyCssClass: "empty-row", // CSS class applied to the empty row
140 formCssClass: "dynamic-form", // CSS class applied to each form in a formset
206 formCssClass: "dynamic-form", // CSS class applied to each form in a formset
141 added: null, // Function called each time a new form is added
207 added: null, // Function called each time a new form is added
142 removed: null, // Function called each time a form is deleted
208 removed: null, // Function called each time a form is deleted
143 addButton: null // Existing add button to use
209 addButton: null // Existing add button to use
144 };
210 };
145
211
146
212
147 // Tabular inlines ---------------------------------------------------------
213 // Tabular inlines ---------------------------------------------------------
148 $.fn.tabularFormset = function(selector, options) {
214 $.fn.tabularFormset = function(selector, options) {
149 var $rows = $(this);
215 const $rows = $(this);
150 var alternatingRows = function(row) {
151 $(selector).not(".add-row").removeClass("row1 row2")
152 .filter(":even").addClass("row1").end()
153 .filter(":odd").addClass("row2");
154 };
155
216
156 var reinitDateTimeShortCuts = function() {
217 const reinitDateTimeShortCuts = function() {
157 // Reinitialize the calendar and clock widgets by force
218 // Reinitialize the calendar and clock widgets by force
158 if (typeof DateTimeShortcuts !== "undefined") {
219 if (typeof DateTimeShortcuts !== "undefined") {
159 $(".datetimeshortcuts").remove();
220 $(".datetimeshortcuts").remove();
@@ -161,24 +222,22
161 }
222 }
162 };
223 };
163
224
164 var updateSelectFilter = function() {
225 const updateSelectFilter = function() {
165 // If any SelectFilter widgets are a part of the new form,
226 // If any SelectFilter widgets are a part of the new form,
166 // instantiate a new SelectFilter instance for it.
227 // instantiate a new SelectFilter instance for it.
167 if (typeof SelectFilter !== 'undefined') {
228 if (typeof SelectFilter !== 'undefined') {
168 $('.selectfilter').each(function(index, value) {
229 $('.selectfilter').each(function(index, value) {
169 var namearr = value.name.split('-');
230 SelectFilter.init(value.id, this.dataset.fieldName, false);
170 SelectFilter.init(value.id, namearr[namearr.length - 1], false);
171 });
231 });
172 $('.selectfilterstacked').each(function(index, value) {
232 $('.selectfilterstacked').each(function(index, value) {
173 var namearr = value.name.split('-');
233 SelectFilter.init(value.id, this.dataset.fieldName, true);
174 SelectFilter.init(value.id, namearr[namearr.length - 1], true);
175 });
234 });
176 }
235 }
177 };
236 };
178
237
179 var initPrepopulatedFields = function(row) {
238 const initPrepopulatedFields = function(row) {
180 row.find('.prepopulated_field').each(function() {
239 row.find('.prepopulated_field').each(function() {
181 var field = $(this),
240 const field = $(this),
182 input = field.find('input, select, textarea'),
241 input = field.find('input, select, textarea'),
183 dependency_list = input.data('dependency_list') || [],
242 dependency_list = input.data('dependency_list') || [],
184 dependencies = [];
243 dependencies = [];
@@ -198,12 +257,10
198 deleteCssClass: "inline-deletelink",
257 deleteCssClass: "inline-deletelink",
199 deleteText: options.deleteText,
258 deleteText: options.deleteText,
200 emptyCssClass: "empty-form",
259 emptyCssClass: "empty-form",
201 removed: alternatingRows,
202 added: function(row) {
260 added: function(row) {
203 initPrepopulatedFields(row);
261 initPrepopulatedFields(row);
204 reinitDateTimeShortCuts();
262 reinitDateTimeShortCuts();
205 updateSelectFilter();
263 updateSelectFilter();
206 alternatingRows(row);
207 },
264 },
208 addButton: options.addButton
265 addButton: options.addButton
209 });
266 });
@@ -213,15 +270,15
213
270
214 // Stacked inlines ---------------------------------------------------------
271 // Stacked inlines ---------------------------------------------------------
215 $.fn.stackedFormset = function(selector, options) {
272 $.fn.stackedFormset = function(selector, options) {
216 var $rows = $(this);
273 const $rows = $(this);
217 var updateInlineLabel = function(row) {
274 const updateInlineLabel = function(row) {
218 $(selector).find(".inline_label").each(function(i) {
275 $(selector).find(".inline_label").each(function(i) {
219 var count = i + 1;
276 const count = i + 1;
220 $(this).html($(this).html().replace(/(#\d+)/g, "#" + count));
277 $(this).html($(this).html().replace(/(#\d+)/g, "#" + count));
221 });
278 });
222 };
279 };
223
280
224 var reinitDateTimeShortCuts = function() {
281 const reinitDateTimeShortCuts = function() {
225 // Reinitialize the calendar and clock widgets by force, yuck.
282 // Reinitialize the calendar and clock widgets by force, yuck.
226 if (typeof DateTimeShortcuts !== "undefined") {
283 if (typeof DateTimeShortcuts !== "undefined") {
227 $(".datetimeshortcuts").remove();
284 $(".datetimeshortcuts").remove();
@@ -229,28 +286,32
229 }
286 }
230 };
287 };
231
288
232 var updateSelectFilter = function() {
289 const updateSelectFilter = function() {
233 // If any SelectFilter widgets were added, instantiate a new instance.
290 // If any SelectFilter widgets were added, instantiate a new instance.
234 if (typeof SelectFilter !== "undefined") {
291 if (typeof SelectFilter !== "undefined") {
235 $(".selectfilter").each(function(index, value) {
292 $(".selectfilter").each(function(index, value) {
236 var namearr = value.name.split('-');
293 SelectFilter.init(value.id, this.dataset.fieldName, false);
237 SelectFilter.init(value.id, namearr[namearr.length - 1], false);
238 });
294 });
239 $(".selectfilterstacked").each(function(index, value) {
295 $(".selectfilterstacked").each(function(index, value) {
240 var namearr = value.name.split('-');
296 SelectFilter.init(value.id, this.dataset.fieldName, true);
241 SelectFilter.init(value.id, namearr[namearr.length - 1], true);
242 });
297 });
243 }
298 }
244 };
299 };
245
300
246 var initPrepopulatedFields = function(row) {
301 const initPrepopulatedFields = function(row) {
247 row.find('.prepopulated_field').each(function() {
302 row.find('.prepopulated_field').each(function() {
248 var field = $(this),
303 const field = $(this),
249 input = field.find('input, select, textarea'),
304 input = field.find('input, select, textarea'),
250 dependency_list = input.data('dependency_list') || [],
305 dependency_list = input.data('dependency_list') || [],
251 dependencies = [];
306 dependencies = [];
252 $.each(dependency_list, function(i, field_name) {
307 $.each(dependency_list, function(i, field_name) {
253 dependencies.push('#' + row.find('.form-row .field-' + field_name).find('input, select, textarea').attr('id'));
308 // Dependency in a fieldset.
309 let field_element = row.find('.form-row .field-' + field_name);
310 // Dependency without a fieldset.
311 if (!field_element.length) {
312 field_element = row.find('.form-row.field-' + field_name);
313 }
314 dependencies.push('#' + field_element.find('input, select, textarea').attr('id'));
254 });
315 });
255 if (dependencies.length) {
316 if (dependencies.length) {
256 input.prepopulate(dependencies, input.attr('maxlength'));
317 input.prepopulate(dependencies, input.attr('maxlength'));
@@ -280,19 +341,19
280
341
281 $(document).ready(function() {
342 $(document).ready(function() {
282 $(".js-inline-admin-formset").each(function() {
343 $(".js-inline-admin-formset").each(function() {
283 var data = $(this).data(),
344 const data = $(this).data(),
284 inlineOptions = data.inlineFormset,
345 inlineOptions = data.inlineFormset;
285 selector;
346 let selector;
286 switch(data.inlineType) {
347 switch(data.inlineType) {
287 case "stacked":
348 case "stacked":
288 selector = inlineOptions.name + "-group .inline-related";
349 selector = inlineOptions.name + "-group .inline-related";
289 $(selector).stackedFormset(selector, inlineOptions.options);
350 $(selector).stackedFormset(selector, inlineOptions.options);
290 break;
351 break;
291 case "tabular":
352 case "tabular":
292 selector = inlineOptions.name + "-group .tabular.inline-related tbody:first > tr";
353 selector = inlineOptions.name + "-group .tabular.inline-related tbody:first > tr.form-row";
293 $(selector).tabularFormset(selector, inlineOptions.options);
354 $(selector).tabularFormset(selector, inlineOptions.options);
294 break;
355 break;
295 }
356 }
296 });
357 });
297 });
358 });
298 })(django.jQuery);
359 }
@@ -1,8 +1,8
1 /*global django:true, jQuery:false*/
1 /*global jQuery:false*/
2 'use strict';
2 /* Puts the included jQuery into our own namespace using noConflict and passing
3 /* Puts the included jQuery into our own namespace using noConflict and passing
3 * it 'true'. This ensures that the included jQuery doesn't pollute the global
4 * it 'true'. This ensures that the included jQuery doesn't pollute the global
4 * namespace (i.e. this preserves pre-existing values for both window.$ and
5 * namespace (i.e. this preserves pre-existing values for both window.$ and
5 * window.jQuery).
6 * window.jQuery).
6 */
7 */
7 var django = django || {};
8 window.django = {jQuery: jQuery.noConflict(true)};
8 django.jQuery = jQuery.noConflict(true);
@@ -1,7 +1,7
1 /*global opener */
1 /*global opener */
2 (function() {
2 'use strict';
3 'use strict';
3 {
4 var initData = JSON.parse(document.getElementById('django-admin-popup-response-constants').dataset.popupResponse);
4 const initData = JSON.parse(document.getElementById('django-admin-popup-response-constants').dataset.popupResponse);
5 switch(initData.action) {
5 switch(initData.action) {
6 case 'change':
6 case 'change':
7 opener.dismissChangeRelatedObjectPopup(window, initData.value, initData.obj, initData.new_value);
7 opener.dismissChangeRelatedObjectPopup(window, initData.value, initData.obj, initData.new_value);
@@ -13,4 +13,4
13 opener.dismissAddRelatedObjectPopup(window, initData.value, initData.obj);
13 opener.dismissAddRelatedObjectPopup(window, initData.value, initData.obj);
14 break;
14 break;
15 }
15 }
16 })();
16 }
@@ -1,6 +1,7
1 /*global URLify*/
1 /*global URLify*/
2 (function($) {
2 'use strict';
3 'use strict';
3 {
4 const $ = django.jQuery;
4 $.fn.prepopulate = function(dependencies, maxLength, allowUnicode) {
5 $.fn.prepopulate = function(dependencies, maxLength, allowUnicode) {
5 /*
6 /*
6 Depends on urlify.js
7 Depends on urlify.js
@@ -11,15 +12,15
11 allowUnicode - Unicode support of the URLify'd string
12 allowUnicode - Unicode support of the URLify'd string
12 */
13 */
13 return this.each(function() {
14 return this.each(function() {
14 var prepopulatedField = $(this);
15 const prepopulatedField = $(this);
15
16
16 var populate = function() {
17 const populate = function() {
17 // Bail if the field's value has been changed by the user
18 // Bail if the field's value has been changed by the user
18 if (prepopulatedField.data('_changed')) {
19 if (prepopulatedField.data('_changed')) {
19 return;
20 return;
20 }
21 }
21
22
22 var values = [];
23 const values = [];
23 $.each(dependencies, function(i, field) {
24 $.each(dependencies, function(i, field) {
24 field = $(field);
25 field = $(field);
25 if (field.val().length > 0) {
26 if (field.val().length > 0) {
@@ -39,4 +40,4
39 }
40 }
40 });
41 });
41 };
42 };
42 })(django.jQuery);
43 }
@@ -1,10 +1,15
1 (function($) {
1 'use strict';
2 'use strict';
2 {
3 var fields = $('#django-admin-prepopulated-fields-constants').data('prepopulatedFields');
3 const $ = django.jQuery;
4 const fields = $('#django-admin-prepopulated-fields-constants').data('prepopulatedFields');
4 $.each(fields, function(index, field) {
5 $.each(fields, function(index, field) {
5 $('.empty-form .form-row .field-' + field.name + ', .empty-form.form-row .field-' + field.name).addClass('prepopulated_field');
6 $(
7 '.empty-form .form-row .field-' + field.name +
8 ', .empty-form.form-row .field-' + field.name +
9 ', .empty-form .form-row.field-' + field.name
10 ).addClass('prepopulated_field');
6 $(field.id).data('dependency_list', field.dependency_list).prepopulate(
11 $(field.id).data('dependency_list', field.dependency_list).prepopulate(
7 field.dependency_ids, field.maxLength, field.allowUnicode
12 field.dependency_ids, field.maxLength, field.allowUnicode
8 );
13 );
9 });
14 });
10 })(django.jQuery);
15 }
@@ -1,8 +1,7
1 /*global XRegExp*/
1 /*global XRegExp*/
2 (function() {
2 'use strict';
3 'use strict';
3 {
4
4 const LATIN_MAP = {
5 var LATIN_MAP = {
6 'À': 'A', 'Á': 'A', 'Â': 'A', 'Ã': 'A', 'Ä': 'A', 'Å': 'A', 'Æ': 'AE',
5 'À': 'A', 'Á': 'A', 'Â': 'A', 'Ã': 'A', 'Ä': 'A', 'Å': 'A', 'Æ': 'AE',
7 'Ç': 'C', 'È': 'E', 'É': 'E', 'Ê': 'E', 'Ë': 'E', 'Ì': 'I', 'Í': 'I',
6 'Ç': 'C', 'È': 'E', 'É': 'E', 'Ê': 'E', 'Ë': 'E', 'Ì': 'I', 'Í': 'I',
8 'Î': 'I', 'Ï': 'I', 'Ð': 'D', 'Ñ': 'N', 'Ò': 'O', 'Ó': 'O', 'Ô': 'O',
7 'Î': 'I', 'Ï': 'I', 'Ð': 'D', 'Ñ': 'N', 'Ò': 'O', 'Ó': 'O', 'Ô': 'O',
@@ -14,10 +13,10
14 'ö': 'o', 'ő': 'o', 'ø': 'o', 'ù': 'u', 'ú': 'u', 'û': 'u', 'ü': 'u',
13 'ö': 'o', 'ő': 'o', 'ø': 'o', 'ù': 'u', 'ú': 'u', 'û': 'u', 'ü': 'u',
15 'ű': 'u', 'ý': 'y', 'þ': 'th', 'ÿ': 'y'
14 'ű': 'u', 'ý': 'y', 'þ': 'th', 'ÿ': 'y'
16 };
15 };
17 var LATIN_SYMBOLS_MAP = {
16 const LATIN_SYMBOLS_MAP = {
18 '©': '(c)'
17 '©': '(c)'
19 };
18 };
20 var GREEK_MAP = {
19 const GREEK_MAP = {
21 'α': 'a', 'β': 'b', 'γ': 'g', 'δ': 'd', 'ε': 'e', 'ζ': 'z', 'η': 'h',
20 'α': 'a', 'β': 'b', 'γ': 'g', 'δ': 'd', 'ε': 'e', 'ζ': 'z', 'η': 'h',
22 'θ': '8', 'ι': 'i', 'κ': 'k', 'λ': 'l', 'μ': 'm', 'ν': 'n', 'ξ': '3',
21 'θ': '8', 'ι': 'i', 'κ': 'k', 'λ': 'l', 'μ': 'm', 'ν': 'n', 'ξ': '3',
23 'ο': 'o', 'π': 'p', 'ρ': 'r', 'σ': 's', 'τ': 't', 'υ': 'y', 'φ': 'f',
22 'ο': 'o', 'π': 'p', 'ρ': 'r', 'σ': 's', 'τ': 't', 'υ': 'y', 'φ': 'f',
@@ -29,15 +28,15
29 'Φ': 'F', 'Χ': 'X', 'Ψ': 'PS', 'Ω': 'W', 'Ά': 'A', 'Έ': 'E', 'Ί': 'I',
28 'Φ': 'F', 'Χ': 'X', 'Ψ': 'PS', 'Ω': 'W', 'Ά': 'A', 'Έ': 'E', 'Ί': 'I',
30 'Ό': 'O', 'Ύ': 'Y', 'Ή': 'H', 'Ώ': 'W', 'Ϊ': 'I', 'Ϋ': 'Y'
29 'Ό': 'O', 'Ύ': 'Y', 'Ή': 'H', 'Ώ': 'W', 'Ϊ': 'I', 'Ϋ': 'Y'
31 };
30 };
32 var TURKISH_MAP = {
31 const TURKISH_MAP = {
33 'ş': 's', 'Ş': 'S', 'ı': 'i', 'İ': 'I', 'ç': 'c', 'Ç': 'C', 'ü': 'u',
32 'ş': 's', 'Ş': 'S', 'ı': 'i', 'İ': 'I', 'ç': 'c', 'Ç': 'C', 'ü': 'u',
34 'Ü': 'U', 'ö': 'o', 'Ö': 'O', 'ğ': 'g', 'Ğ': 'G'
33 'Ü': 'U', 'ö': 'o', 'Ö': 'O', 'ğ': 'g', 'Ğ': 'G'
35 };
34 };
36 var ROMANIAN_MAP = {
35 const ROMANIAN_MAP = {
37 'ă': 'a', 'î': 'i', 'ș': 's', 'ț': 't', 'â': 'a',
36 'ă': 'a', 'î': 'i', 'ș': 's', 'ț': 't', 'â': 'a',
38 'Ă': 'A', 'Î': 'I', 'Ș': 'S', 'Ț': 'T', 'Â': 'A'
37 'Ă': 'A', 'Î': 'I', 'Ș': 'S', 'Ț': 'T', 'Â': 'A'
39 };
38 };
40 var RUSSIAN_MAP = {
39 const RUSSIAN_MAP = {
41 'а': 'a', 'б': 'b', 'в': 'v', 'г': 'g', 'д': 'd', 'е': 'e', 'ё': 'yo',
40 'а': 'a', 'б': 'b', 'в': 'v', 'г': 'g', 'д': 'd', 'е': 'e', 'ё': 'yo',
42 'ж': 'zh', 'з': 'z', 'и': 'i', 'й': 'j', 'к': 'k', 'л': 'l', 'м': 'm',
41 'ж': 'zh', 'з': 'z', 'и': 'i', 'й': 'j', 'к': 'k', 'л': 'l', 'м': 'm',
43 'н': 'n', 'о': 'o', 'п': 'p', 'р': 'r', 'с': 's', 'т': 't', 'у': 'u',
42 'н': 'n', 'о': 'o', 'п': 'p', 'р': 'r', 'с': 's', 'т': 't', 'у': 'u',
@@ -49,16 +48,16
49 'Ф': 'F', 'Х': 'H', 'Ц': 'C', 'Ч': 'Ch', 'Ш': 'Sh', 'Щ': 'Sh', 'Ъ': '',
48 'Ф': 'F', 'Х': 'H', 'Ц': 'C', 'Ч': 'Ch', 'Ш': 'Sh', 'Щ': 'Sh', 'Ъ': '',
50 'Ы': 'Y', 'Ь': '', 'Э': 'E', 'Ю': 'Yu', 'Я': 'Ya'
49 'Ы': 'Y', 'Ь': '', 'Э': 'E', 'Ю': 'Yu', 'Я': 'Ya'
51 };
50 };
52 var UKRAINIAN_MAP = {
51 const UKRAINIAN_MAP = {
53 'Є': 'Ye', 'І': 'I', 'Ї': 'Yi', 'Ґ': 'G', 'є': 'ye', 'і': 'i',
52 'Є': 'Ye', 'І': 'I', 'Ї': 'Yi', 'Ґ': 'G', 'є': 'ye', 'і': 'i',
54 'ї': 'yi', 'ґ': 'g'
53 'ї': 'yi', 'ґ': 'g'
55 };
54 };
56 var CZECH_MAP = {
55 const CZECH_MAP = {
57 'č': 'c', 'ď': 'd', 'ě': 'e', 'ň': 'n', 'ř': 'r', 'š': 's', 'ť': 't',
56 'č': 'c', 'ď': 'd', 'ě': 'e', 'ň': 'n', 'ř': 'r', 'š': 's', 'ť': 't',
58 'ů': 'u', 'ž': 'z', 'Č': 'C', 'Ď': 'D', 'Ě': 'E', 'Ň': 'N', 'Ř': 'R',
57 'ů': 'u', 'ž': 'z', 'Č': 'C', 'Ď': 'D', 'Ě': 'E', 'Ň': 'N', 'Ř': 'R',
59 'Š': 'S', 'Ť': 'T', 'Ů': 'U', 'Ž': 'Z'
58 'Š': 'S', 'Ť': 'T', 'Ů': 'U', 'Ž': 'Z'
60 };
59 };
61 var SLOVAK_MAP = {
60 const SLOVAK_MAP = {
62 'á': 'a', 'ä': 'a', 'č': 'c', 'ď': 'd', 'é': 'e', 'í': 'i', 'ľ': 'l',
61 'á': 'a', 'ä': 'a', 'č': 'c', 'ď': 'd', 'é': 'e', 'í': 'i', 'ľ': 'l',
63 'ĺ': 'l', 'ň': 'n', 'ó': 'o', 'ô': 'o', 'ŕ': 'r', 'š': 's', 'ť': 't',
62 'ĺ': 'l', 'ň': 'n', 'ó': 'o', 'ô': 'o', 'ŕ': 'r', 'š': 's', 'ť': 't',
64 'ú': 'u', 'ý': 'y', 'ž': 'z',
63 'ú': 'u', 'ý': 'y', 'ž': 'z',
@@ -66,40 +65,40
66 'Ĺ': 'L', 'Ň': 'N', 'Ó': 'O', 'Ô': 'O', 'Ŕ': 'R', 'Š': 'S', 'Ť': 'T',
65 'Ĺ': 'L', 'Ň': 'N', 'Ó': 'O', 'Ô': 'O', 'Ŕ': 'R', 'Š': 'S', 'Ť': 'T',
67 'Ú': 'U', 'Ý': 'Y', 'Ž': 'Z'
66 'Ú': 'U', 'Ý': 'Y', 'Ž': 'Z'
68 };
67 };
69 var POLISH_MAP = {
68 const POLISH_MAP = {
70 'ą': 'a', 'ć': 'c', 'ę': 'e', 'ł': 'l', 'ń': 'n', 'ó': 'o', 'ś': 's',
69 'ą': 'a', 'ć': 'c', 'ę': 'e', 'ł': 'l', 'ń': 'n', 'ó': 'o', 'ś': 's',
71 'ź': 'z', 'ż': 'z',
70 'ź': 'z', 'ż': 'z',
72 'Ą': 'A', 'Ć': 'C', 'Ę': 'E', 'Ł': 'L', 'Ń': 'N', 'Ó': 'O', 'Ś': 'S',
71 'Ą': 'A', 'Ć': 'C', 'Ę': 'E', 'Ł': 'L', 'Ń': 'N', 'Ó': 'O', 'Ś': 'S',
73 'Ź': 'Z', 'Ż': 'Z'
72 'Ź': 'Z', 'Ż': 'Z'
74 };
73 };
75 var LATVIAN_MAP = {
74 const LATVIAN_MAP = {
76 'ā': 'a', 'č': 'c', 'ē': 'e', 'ģ': 'g', 'ī': 'i', 'ķ': 'k', 'ļ': 'l',
75 'ā': 'a', 'č': 'c', 'ē': 'e', 'ģ': 'g', 'ī': 'i', 'ķ': 'k', 'ļ': 'l',
77 'ņ': 'n', 'š': 's', 'ū': 'u', 'ž': 'z',
76 'ņ': 'n', 'š': 's', 'ū': 'u', 'ž': 'z',
78 'Ā': 'A', 'Č': 'C', 'Ē': 'E', 'Ģ': 'G', 'Ī': 'I', 'Ķ': 'K', 'Ļ': 'L',
77 'Ā': 'A', 'Č': 'C', 'Ē': 'E', 'Ģ': 'G', 'Ī': 'I', 'Ķ': 'K', 'Ļ': 'L',
79 'Ņ': 'N', 'Š': 'S', 'Ū': 'U', 'Ž': 'Z'
78 'Ņ': 'N', 'Š': 'S', 'Ū': 'U', 'Ž': 'Z'
80 };
79 };
81 var ARABIC_MAP = {
80 const ARABIC_MAP = {
82 'أ': 'a', 'ب': 'b', 'ت': 't', 'ث': 'th', 'ج': 'g', 'ح': 'h', 'خ': 'kh', 'د': 'd',
81 'أ': 'a', 'ب': 'b', 'ت': 't', 'ث': 'th', 'ج': 'g', 'ح': 'h', 'خ': 'kh', 'د': 'd',
83 'ذ': 'th', 'ر': 'r', 'ز': 'z', 'س': 's', 'ش': 'sh', 'ص': 's', 'ض': 'd', 'ط': 't',
82 'ذ': 'th', 'ر': 'r', 'ز': 'z', 'س': 's', 'ش': 'sh', 'ص': 's', 'ض': 'd', 'ط': 't',
84 'ظ': 'th', 'ع': 'aa', 'غ': 'gh', 'ف': 'f', 'ق': 'k', 'ك': 'k', 'ل': 'l', 'م': 'm',
83 'ظ': 'th', 'ع': 'aa', 'غ': 'gh', 'ف': 'f', 'ق': 'k', 'ك': 'k', 'ل': 'l', 'م': 'm',
85 'ن': 'n', 'ه': 'h', 'و': 'o', 'ي': 'y'
84 'ن': 'n', 'ه': 'h', 'و': 'o', 'ي': 'y'
86 };
85 };
87 var LITHUANIAN_MAP = {
86 const LITHUANIAN_MAP = {
88 'ą': 'a', 'č': 'c', 'ę': 'e', 'ė': 'e', 'į': 'i', 'š': 's', 'ų': 'u',
87 'ą': 'a', 'č': 'c', 'ę': 'e', 'ė': 'e', 'į': 'i', 'š': 's', 'ų': 'u',
89 'ū': 'u', 'ž': 'z',
88 'ū': 'u', 'ž': 'z',
90 'Ą': 'A', 'Č': 'C', 'Ę': 'E', 'Ė': 'E', 'Į': 'I', 'Š': 'S', 'Ų': 'U',
89 'Ą': 'A', 'Č': 'C', 'Ę': 'E', 'Ė': 'E', 'Į': 'I', 'Š': 'S', 'Ų': 'U',
91 'Ū': 'U', 'Ž': 'Z'
90 'Ū': 'U', 'Ž': 'Z'
92 };
91 };
93 var SERBIAN_MAP = {
92 const SERBIAN_MAP = {
94 'ђ': 'dj', 'ј': 'j', 'љ': 'lj', 'њ': 'nj', 'ћ': 'c', 'џ': 'dz',
93 'ђ': 'dj', 'ј': 'j', 'љ': 'lj', 'њ': 'nj', 'ћ': 'c', 'џ': 'dz',
95 'đ': 'dj', 'Ђ': 'Dj', 'Ј': 'j', 'Љ': 'Lj', 'Њ': 'Nj', 'Ћ': 'C',
94 'đ': 'dj', 'Ђ': 'Dj', 'Ј': 'j', 'Љ': 'Lj', 'Њ': 'Nj', 'Ћ': 'C',
96 'Џ': 'Dz', 'Đ': 'Dj'
95 'Џ': 'Dz', 'Đ': 'Dj'
97 };
96 };
98 var AZERBAIJANI_MAP = {
97 const AZERBAIJANI_MAP = {
99 'ç': 'c', 'ə': 'e', 'ğ': 'g', 'ı': 'i', 'ö': 'o', 'ş': 's', 'ü': 'u',
98 'ç': 'c', 'ə': 'e', 'ğ': 'g', 'ı': 'i', 'ö': 'o', 'ş': 's', 'ü': 'u',
100 'Ç': 'C', 'Ə': 'E', 'Ğ': 'G', 'İ': 'I', 'Ö': 'O', 'Ş': 'S', 'Ü': 'U'
99 'Ç': 'C', 'Ə': 'E', 'Ğ': 'G', 'İ': 'I', 'Ö': 'O', 'Ş': 'S', 'Ü': 'U'
101 };
100 };
102 var GEORGIAN_MAP = {
101 const GEORGIAN_MAP = {
103 'ა': 'a', 'ბ': 'b', 'გ': 'g', 'დ': 'd', 'ე': 'e', 'ვ': 'v', 'ზ': 'z',
102 'ა': 'a', 'ბ': 'b', 'გ': 'g', 'დ': 'd', 'ე': 'e', 'ვ': 'v', 'ზ': 'z',
104 'თ': 't', 'ი': 'i', 'კ': 'k', 'ლ': 'l', 'მ': 'm', 'ნ': 'n', 'ო': 'o',
103 'თ': 't', 'ი': 'i', 'კ': 'k', 'ლ': 'l', 'მ': 'm', 'ნ': 'n', 'ო': 'o',
105 'პ': 'p', 'ჟ': 'j', 'რ': 'r', 'ს': 's', 'ტ': 't', 'უ': 'u', 'ფ': 'f',
104 'პ': 'p', 'ჟ': 'j', 'რ': 'r', 'ს': 's', 'ტ': 't', 'უ': 'u', 'ფ': 'f',
@@ -107,7 +106,7
107 'წ': 'w', 'ჭ': 'ch', 'ხ': 'x', 'ჯ': 'j', 'ჰ': 'h'
106 'წ': 'w', 'ჭ': 'ch', 'ხ': 'x', 'ჯ': 'j', 'ჰ': 'h'
108 };
107 };
109
108
110 var ALL_DOWNCODE_MAPS = [
109 const ALL_DOWNCODE_MAPS = [
111 LATIN_MAP,
110 LATIN_MAP,
112 LATIN_SYMBOLS_MAP,
111 LATIN_SYMBOLS_MAP,
113 GREEK_MAP,
112 GREEK_MAP,
@@ -126,27 +125,16
126 GEORGIAN_MAP
125 GEORGIAN_MAP
127 ];
126 ];
128
127
129 var Downcoder = {
128 const Downcoder = {
130 'Initialize': function() {
129 'Initialize': function() {
131 if (Downcoder.map) { // already made
130 if (Downcoder.map) { // already made
132 return;
131 return;
133 }
132 }
134 Downcoder.map = {};
133 Downcoder.map = {};
135 Downcoder.chars = [];
134 for (const lookup of ALL_DOWNCODE_MAPS) {
136 for (var i = 0; i < ALL_DOWNCODE_MAPS.length; i++) {
135 Object.assign(Downcoder.map, lookup);
137 var lookup = ALL_DOWNCODE_MAPS[i];
138 for (var c in lookup) {
139 if (lookup.hasOwnProperty(c)) {
140 Downcoder.map[c] = lookup[c];
141 }
142 }
143 }
144 for (var k in Downcoder.map) {
145 if (Downcoder.map.hasOwnProperty(k)) {
146 Downcoder.chars.push(k);
147 }
148 }
136 }
149 Downcoder.regex = new RegExp(Downcoder.chars.join('|'), 'g');
137 Downcoder.regex = new RegExp(Object.keys(Downcoder.map).join('|'), 'g');
150 }
138 }
151 };
139 };
152
140
@@ -160,36 +148,23
160
148
161 function URLify(s, num_chars, allowUnicode) {
149 function URLify(s, num_chars, allowUnicode) {
162 // changes, e.g., "Petty theft" to "petty-theft"
150 // changes, e.g., "Petty theft" to "petty-theft"
163 // remove all these words from the string before urlifying
164 if (!allowUnicode) {
151 if (!allowUnicode) {
165 s = downcode(s);
152 s = downcode(s);
166 }
153 }
167 var hasUnicodeChars = /[^\u0000-\u007f]/.test(s);
154 s = s.toLowerCase(); // convert to lowercase
168 // Remove English words only if the string contains ASCII (English)
169 // characters.
170 if (!hasUnicodeChars) {
171 var removeList = [
172 "a", "an", "as", "at", "before", "but", "by", "for", "from",
173 "is", "in", "into", "like", "of", "off", "on", "onto", "per",
174 "since", "than", "the", "this", "that", "to", "up", "via",
175 "with"
176 ];
177 var r = new RegExp('\\b(' + removeList.join('|') + ')\\b', 'gi');
178 s = s.replace(r, '');
179 }
180 // if downcode doesn't hit, the char will be stripped here
155 // if downcode doesn't hit, the char will be stripped here
181 if (allowUnicode) {
156 if (allowUnicode) {
182 // Keep Unicode letters including both lowercase and uppercase
157 // Keep Unicode letters including both lowercase and uppercase
183 // characters, whitespace, and dash; remove other characters.
158 // characters, whitespace, and dash; remove other characters.
184 s = XRegExp.replace(s, XRegExp('[^-_\\p{L}\\p{N}\\s]', 'g'), '');
159 s = XRegExp.replace(s, XRegExp('[^-_\\p{L}\\p{N}\\s]', 'g'), '');
185 } else {
160 } else {
186 s = s.replace(/[^-\w\s]/g, ''); // remove unneeded chars
161 s = s.replace(/[^-\w\s]/g, ''); // remove unneeded chars
187 }
162 }
188 s = s.replace(/^\s+|\s+$/g, ''); // trim leading/trailing spaces
163 s = s.replace(/^\s+|\s+$/g, ''); // trim leading/trailing spaces
189 s = s.replace(/[-\s]+/g, '-'); // convert spaces to hyphens
164 s = s.replace(/[-\s]+/g, '-'); // convert spaces to hyphens
190 s = s.substring(0, num_chars); // trim to first num_chars chars
165 s = s.substring(0, num_chars); // trim to first num_chars chars
191 s = s.replace(/-+$/g, ''); // trim any trailing hyphens
166 s = s.replace(/-+$/g, ''); // trim any trailing hyphens
192 return s.toLowerCase(); // convert to lowercase
167 return s;
193 }
168 }
194 window.URLify = URLify;
169 window.URLify = URLify;
195 })();
170 }
@@ -1,10 +1,4
1 Copyright jQuery Foundation and other contributors, https://jquery.org/
1 Copyright OpenJS Foundation and other contributors, https://openjsf.org/
2
3 This software consists of voluntary contributions made by many
4 individuals. For exact contribution history, see the revision history
5 available at https://github.com/jquery/jquery
6
7 ====
8
2
9 Permission is hereby granted, free of charge, to any person obtaining
3 Permission is hereby granted, free of charge, to any person obtaining
10 a copy of this software and associated documentation files (the
4 a copy of this software and associated documentation files (the
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
General Comments 0
You need to be logged in to leave comments. Login now