414 Commits

Author SHA1 Message Date
6e57c28d4b add conf to have access to folder gallery 2025-10-27 20:02:33 +01:00
153e937bfe add conf to have access to folder assets 2025-10-27 20:00:58 +01:00
719774dcf4 delete the word 'Honorarnoten' 2025-10-26 23:57:37 +01:00
bdad7a38b1 Update all assets 2025-10-23 19:03:15 +02:00
094d7bed13 update homepage version to 2.2.0 2025-10-23 18:54:05 +02:00
8d4f899184 delete insecure option 2025-10-23 18:53:29 +02:00
245679da83 update mode of docker-entrypoint if linux 2025-10-23 18:48:01 +02:00
a724d07b96 add all new migrations 2025-10-23 18:47:09 +02:00
e6b6bdbf12 fix condition :D 2025-10-23 18:31:41 +02:00
ec3c15e5a1 change url name 2025-10-23 18:14:33 +02:00
a3ffde3206 fix that you could not see the token in dark mode. 2025-10-23 18:12:51 +02:00
2b25ad30af add new rental rules 2025-10-23 17:47:30 +02:00
sebivh
b5af399ca1 Fix error with database query 2025-10-21 18:28:37 +02:00
sebivh
1ebc551370 add +x flag to mode 2025-10-21 17:57:34 +02:00
sebivh
b7aaedba14 Added Authentication for Minecraft Server
In this commit, a beautiful authentication method was added! It can be
uses to authenticate SECURLY!!!! with the McFet Plugin! This is pretty
USEFULL!!!
2025-10-20 15:22:58 +02:00
7b16f85dd1 update gitignore 2025-10-17 14:27:00 +02:00
0a67502dc5 update README 2025-10-17 14:26:48 +02:00
34ec726c10 update docker compose 2025-10-17 14:25:48 +02:00
54f9394673 add nginx conf for homepage 2025-10-17 14:25:06 +02:00
fc8de40524 add dockerfile only for django project 2025-10-17 14:21:50 +02:00
fb3466ff63 change package management for developing to uv 2025-10-17 14:19:47 +02:00
cd9c81cfc2 add python-version file for uv 2025-10-17 14:12:46 +02:00
83cbf037fc deactivate pdf render 2025-10-17 00:57:41 +02:00
484dce8305 add rental calendar 2025-10-14 13:44:34 +02:00
1a47dd2165 Add autofocus to firstname field 2025-07-18 11:34:12 +02:00
1b73b94e07 Refactor baseform templates 2025-07-18 11:33:29 +02:00
7b78368eb0 Set logging level for Image module to info 2025-07-16 22:53:07 +02:00
8939fe5776 improve form layout 2025-07-16 22:33:12 +02:00
96b2549503 better file display 2025-07-16 22:30:47 +02:00
60f231d908 fix css style 2025-07-16 21:16:56 +02:00
42b80bd143 add Verleihformular 2025-07-16 19:21:47 +02:00
15e8ffc3c8 remove dead code 2025-07-05 12:07:50 +02:00
ead98785de remove feature 'fee' 2025-06-25 23:30:15 +02:00
0ae2c86e90 update django to 5.2.3 2025-06-19 16:34:58 +02:00
f107c3dd13 update segno to 1.6.6 2025-06-19 16:34:36 +02:00
d975477705 update pypdf to 5.6.0 2025-06-19 16:34:16 +02:00
022e8537c5 update html2text to 2025.4.15 2025-06-19 16:33:50 +02:00
6bc265bdd8 update djangorestframework to 3.16.0 2025-06-19 14:26:12 +02:00
5922340ebc formatting 2025-03-08 22:10:18 +01:00
c9c33d780f update tailwindcss to 3.4.17 and flowbite to 3.1.2 2025-03-08 21:59:54 +01:00
7a7ddc034b update mail address and message 2025-03-08 14:20:40 +01:00
4f57e01326 delete django-crontab 2025-03-05 21:59:08 +01:00
aef9a0871b update xhtml2pdf to 0.2.17 2025-03-05 21:44:45 +01:00
14617e5492 update django to 5.1.6 2025-03-05 21:42:06 +01:00
4ee9b3eaa5 update django-ckeditor to 6.7.2 2025-03-05 21:41:15 +01:00
faad8635e5 update django-environ to 0.12.0 2025-03-05 21:40:28 +01:00
ed9d115361 update django-filter to 25.1 2025-03-05 21:39:24 +01:00
b24a17b3b6 update django-taggit to 6.1.0 2025-03-05 21:15:52 +01:00
c0fe059e78 update pypdf to 5.3.1 2025-03-05 21:15:26 +01:00
4c669c0fb6 update python-dateutil to 2.9.0.post0 2025-03-05 21:15:01 +01:00
3db68f4bf4 add aria-label 2025-03-05 21:12:06 +01:00
77d18cf58c add detailview, mail sending and new db values 2025-03-05 21:11:03 +01:00
dc263ee28c ruff formating 2025-03-05 17:51:23 +01:00
97c01c4a97 add filter, search text and per page choices 2025-03-05 15:43:20 +01:00
c6684122ea add spacing 2025-03-05 14:06:43 +01:00
5b0b071564 add whatsapp channel 2025-02-25 21:32:05 +01:00
4e278fccab delete crontab 2025-02-22 18:32:03 +01:00
e17d12a079 use hyphen from tailwind-css instead of django-softhypen 2025-02-22 18:27:14 +01:00
1cfe36197f version is only visible for auth user 2025-02-22 18:17:53 +01:00
2e55fae418 Simplify if condition 2025-02-22 18:16:57 +01:00
c15d60ac6a update classes 2025-02-22 18:15:45 +01:00
e98da4426a update fields and wordings 2025-02-22 18:14:34 +01:00
97f2425434 fix max number of rental item filters 2025-02-22 16:12:18 +01:00
3adc98144f add rental 2025-02-22 15:24:13 +01:00
1f3fc92f6b add own bills to bankdata admin view 2025-02-07 14:45:41 +01:00
0ee85a2a77 fix import 2025-02-07 14:41:06 +01:00
6bbb92e9a9 add image extensions 2025-02-07 13:34:29 +01:00
23544cbaff fix type 2025-02-07 13:28:49 +01:00
58b74bdfab add fee 2025-02-07 13:26:47 +01:00
f6ffcd37da formatting 2025-02-04 00:42:25 +01:00
3fd408846e update django to 5.1.5 2025-02-04 00:41:21 +01:00
591b757a8e add python-dateutil 2025-02-04 00:40:35 +01:00
bc105eefcd Displayed only permanent and max 2 years old finance resolutions 2025-02-02 13:11:57 +01:00
2bc64cdc5b code optimization 2025-02-02 12:42:20 +01:00
ace625a530 update template to previous changes 2025-02-02 12:41:08 +01:00
b1e02bbf0a code optimization 2025-02-01 14:51:31 +01:00
ad74ae2c51 Code optimization 2025-02-01 01:21:44 +01:00
e68c2eca63 Renaming words 2025-01-29 23:32:59 +01:00
8121a45ead add default storage for easy thumbnail 2025-01-29 23:06:16 +01:00
c2b6dfa3e4 Add app model sorting for finance and alphabet sorting for others 2025-01-29 23:05:04 +01:00
a7ee650729 fix total being not zero when adding a new resolution 2025-01-29 19:48:36 +01:00
6d5694a153 format_html formatting 2025-01-27 01:05:33 +01:00
c897b5be08 replace string with enum 2025-01-27 01:04:55 +01:00
fcf63d8bf9 ruff formatting 2025-01-27 01:02:42 +01:00
f0d0c44fd6 djade formatting 2025-01-26 22:42:20 +01:00
f999a98d7c add a new Vorlage file, update number of bill to 10 and fix text to multiline 2025-01-26 22:06:16 +01:00
9b05663cf5 delete old stuffs 2025-01-26 15:12:57 +01:00
532b834629 update api key path 2025-01-26 13:13:56 +01:00
57b3e2144e update media url and context processor 2025-01-26 13:13:09 +01:00
5cac8f8275 change ldap auth to ldap backend to be able to program without ldap 2025-01-26 13:10:35 +01:00
dd401538d3 update mysqlclient to 2.2.7 2025-01-18 16:29:46 +01:00
08a0f43fff update pillow to 11.1.0 2025-01-18 16:28:36 +01:00
9663df15d3 update xhtml2pdf to 0.2.16 2025-01-18 16:18:19 +01:00
bf13b1ebd2 update pypdf to 5.1.0 2025-01-18 00:15:09 +01:00
e80094f1bf fix month number of January 2025-01-18 00:14:20 +01:00
2138f6da24 black formatting 2024-09-07 21:14:11 +02:00
be234907cc update django-filter to 24.3 2024-09-07 20:47:36 +02:00
0455c6ec62 update django-haystack to 3.3.0 2024-09-07 20:45:08 +02:00
f82582a449 update django-static-jquery-ui to 1.13.3.1 2024-09-07 20:23:25 +02:00
8c9f9702d7 update django-taggit to 6.0.0 2024-09-07 20:15:25 +02:00
8feb25d7f7 update djangorestframework to 3.15.2 2024-09-07 20:14:10 +02:00
c70f6228bd update easy-thumbnails to 2.9 2024-09-07 20:12:45 +02:00
eb232b7f56 update html2text to 2024.2.26 2024-09-07 20:03:57 +02:00
4bf74ded5a update segno to 1.6.1 2024-09-07 19:52:00 +02:00
f0763d2c05 update fontawesomefree to 6.6.0 2024-09-07 19:42:45 +02:00
a7d951dbab change duration of pinned events to 1 day 2024-09-06 16:21:27 +02:00
13d7969532 fix the order when getting next or prev post and at the post view 2024-08-25 20:37:17 +02:00
f121239d31 News are now pinned for 1 month and events for 7 days. 2024-08-21 16:59:27 +02:00
4134ad67d5 use correct variable for condtion 2024-08-11 12:21:17 +02:00
d8dec47c6a add listfilter for filter bills in periods 2024-08-10 17:51:30 +02:00
2f94b0f510 code formatting (black, isort and flake8) 2024-08-10 17:48:08 +02:00
9408208ed6 fix condition 2024-08-09 14:10:20 +02:00
555f4ebe49 del print 2024-08-06 01:34:15 +02:00
opruffy
3419f8b044 rework posts models and ep api 2024-08-06 01:30:39 +02:00
baa0845344 add link 'view on site' 2024-03-04 22:30:11 +00:00
2990cfd2cd add link to fetmeeting 2024-03-04 22:29:20 +00:00
797ff84b32 add wiref id to qs if wiref is already transferred 2024-03-04 18:04:12 +00:00
4d8088fb3e add mitmachen as a page 2024-02-23 15:17:23 +00:00
65b0e2494c rename incomplete 2024-02-17 10:53:21 +00:00
c831000fae bill creator is only required if a user add a new bill 2024-02-17 10:51:29 +00:00
2c80bb3c88 move shortcut icon 2024-02-17 10:26:00 +00:00
1bb359b322 add safe option to text of textarea 2024-02-17 10:25:34 +00:00
18f73b5f21 update getting cleaned data 2024-02-17 10:24:58 +00:00
a4cba458ee update django to 4.2.10 2024-02-06 22:58:04 +00:00
ce97a5f27e add affiliation to bill inline 2024-02-05 18:27:50 +00:00
de14fdc9d3 update text deco 2024-02-04 22:34:16 +00:00
dcc9f13804 add detail 2024-02-04 21:45:56 +00:00
c219059cb3 update design 2024-02-04 21:29:18 +00:00
0483c9b7dc update fontawesomefree to 6.5.1 2024-02-04 21:06:07 +00:00
36627adb94 update django-taggit to 5.0.1 2024-02-04 21:03:39 +00:00
04f878dd9f update django-filter to 23.5 2024-02-04 20:47:05 +00:00
3f8241cc63 del unused import 2024-01-30 22:23:19 +00:00
8dd9ab1511 use format_html instead of mark_safe 2024-01-30 22:19:47 +00:00
99b06b78a5 if no input, all posts are shown 2024-01-30 18:15:10 +00:00
ec3c11467f delete old flowbite version 2024-01-30 17:43:22 +00:00
d1c235f7cb black formatting 2024-01-30 17:31:33 +00:00
a23321a98b add incomplete status to update view and update other status here 2024-01-29 23:05:56 +00:00
491a81aece update migration 2024-01-29 21:46:01 +00:00
53d099a55c update assets 2024-01-29 21:43:49 +00:00
c16bcb9291 black 2024-01-29 21:43:35 +00:00
327b84d137 change pymupdf to pypdf 2024-01-28 10:31:01 +00:00
89eb72f8c1 fix syntax again 2024-01-28 08:59:57 +00:00
9359a1ae52 fix syntax 2024-01-28 08:54:50 +00:00
9f21a16ab3 add pymupdf again 2024-01-28 08:51:15 +00:00
8512c82d3f delete pymupdf temporary 2024-01-28 08:28:15 +00:00
6248a5343a fix again 2024-01-28 07:43:15 +00:00
a6bb11d64d fix again 2024-01-28 07:24:31 +00:00
3991895ac2 fix again 2024-01-28 07:12:43 +00:00
d91f4c6228 dix dockerfile again 2024-01-28 06:59:29 +00:00
2f4a53d1ce fix dockerfile 2024-01-28 06:44:30 +00:00
35749c2ff6 add mupdf-dev 2024-01-27 11:36:59 +00:00
f22de7d919 set PYMUPDF_SETUP_MUPDF_TESSERACT to 0 2024-01-27 11:09:07 +00:00
3e2d124a63 fix pymupdf req 2024-01-27 10:57:29 +00:00
21aaef068b update assets 2024-01-24 01:15:25 +00:00
803610ea5e optimize get url and get filename functions for agenda and protocol 2024-01-24 01:15:11 +00:00
f58006f6c6 update link to resolution list 2024-01-24 00:23:53 +00:00
3e2022f353 add order to jobs sidebar 2024-01-24 00:18:05 +00:00
7ca73f65f8 update flowbite to 2.2.1 2024-01-24 00:01:27 +00:00
762cda8b20 update design 2024-01-23 23:58:29 +00:00
5f5414f29a use PEP 572 2024-01-23 23:38:59 +00:00
2eadadc452 change breakpoint to lg 2024-01-23 22:52:41 +00:00
c0301d97fe login username is always lowercase 2024-01-23 19:53:37 +00:00
0f2e3a0d8a add bic as required if private payer 2024-01-23 19:11:43 +00:00
938c3e1bdd fix button 2024-01-23 01:33:09 +00:00
906c3da007 update text color 2024-01-23 00:59:40 +00:00
798dba3fe6 add saving button and iban/bic has no whitespace 2024-01-23 00:59:24 +00:00
aa2d8b385f update design for bill_update 2024-01-22 22:35:44 +00:00
aa5e45c430 fix div 2024-01-22 22:32:53 +00:00
d11dc8d7fe update design for bill_create 2024-01-22 22:15:53 +00:00
ced2a1dfab add option to list 2024-01-22 22:13:45 +00:00
706b711d22 change from pymupdf to pymupdfb 2024-01-22 16:31:08 +00:00
56cec2bc44 downgrade pymupdf to 1.23.9 2024-01-22 00:57:06 +00:00
7f139b2172 downgrade pymupdf to 1.23.11 2024-01-22 00:47:23 +00:00
d73d7b329f add package pymupdf 2024-01-21 23:49:40 +00:00
da3586b38e update assets 2024-01-21 22:32:24 +00:00
ff78e823db add migrations 2024-01-21 22:29:10 +00:00
bcf8956c05 update design and add pagination 2024-01-21 22:26:50 +00:00
77811f4017 add order by name 2024-01-18 22:53:33 +00:00
5db1887e40 add bic to admin list 2024-01-18 22:51:32 +00:00
0091339014 fix condition for changing status to submitted 2024-01-18 22:44:41 +00:00
51d6a89d11 add bank data if available 2024-01-17 20:05:56 +00:00
28d37933cd update django to 4.2.9 2024-01-17 19:52:13 +00:00
f01eb87f08 formatting 2024-01-17 19:47:06 +00:00
4b01e89265 add resolution update 2024-01-17 17:51:28 +00:00
9292eaf1cf add name 2024-01-17 17:49:43 +00:00
d11dace81f update bill list view 2024-01-17 17:40:38 +00:00
d560f56d86 update css 2024-01-17 17:38:28 +00:00
8c6685a12c add filter status 2024-01-17 14:33:21 +00:00
1b9a6aeec3 add automatically generation of wiref pdf 2024-01-17 14:32:09 +00:00
d83f14894c fix naming 2024-01-17 13:21:09 +00:00
4bb673f096 filter by opened status 2024-01-17 13:17:44 +00:00
5ce1b3b4f9 move qr code to admin fieldsets 2024-01-12 15:20:32 +00:00
54e8675b15 update status 2024-01-12 15:19:47 +00:00
e2cb2c8a90 update message 2024-01-10 10:28:46 +00:00
45279aac8d add status to wiref 2024-01-10 10:24:48 +00:00
d54a632d67 update ordering, queryset 2024-01-10 10:00:32 +00:00
fee676d0c5 add exception message 2024-01-07 12:20:37 +00:00
8073215888 add qr code 2024-01-05 20:18:24 +00:00
a0fd1844f2 fix import 2023-11-25 21:25:20 +00:00
8c17506a4b fix if condition 2023-11-25 21:19:23 +00:00
c9d4a09203 add optional if not required 2023-11-24 19:11:53 +00:00
dab1391a07 add autofocus 2023-11-24 18:58:45 +00:00
0682df6472 update form to baseform, autofocus to all form 2023-11-24 18:56:48 +00:00
3f9e41a7e7 add autofocus 2023-11-24 18:17:17 +00:00
46d715d96e add event_end as optional 2023-11-24 18:04:49 +00:00
21abfa5eda check if key exists before creating key and rename functions 2023-11-24 17:45:15 +00:00
eb782d879c add migration 2023-11-23 11:35:09 +00:00
cdb36aaf1a update django to 4.2.7 2023-11-23 11:34:20 +00:00
48f36b54f7 rework etherpad functions 2023-11-23 11:14:22 +00:00
c01d4bb4a4 simplify admin register 2023-11-21 18:55:08 +00:00
ec7e225783 isort 2023-11-20 21:43:18 +00:00
d2ffadf96a delete some task stuffs 2023-11-20 21:26:43 +00:00
39247b3e46 flake8 2023-11-20 21:26:14 +00:00
2ff9b47983 avoid pre-formatting log messages 2023-11-20 20:43:55 +00:00
e648a45aa9 delete unused imports 2023-11-20 20:26:38 +00:00
16fa0064dd add ordering and search fields 2023-11-18 16:56:03 +00:00
12b8d13a45 sorted by ID 2023-11-18 16:45:30 +00:00
178cb9e53f add representation to affiliation 2023-11-15 18:14:35 +00:00
3c387c22c6 add payer to list_filter 2023-11-15 18:13:38 +00:00
71117b8e63 created primary keys are not editable 2023-11-15 17:54:06 +00:00
b4a288be0a update string for resolution 2023-11-15 16:08:58 +00:00
6f94bceb08 add pillow because it only works with this version 9.5.0 2023-11-13 08:54:04 +00:00
13f7080503 delete app tasks 2023-11-13 08:52:18 +00:00
0a3e343adb set username if not equal 2023-11-13 08:50:39 +00:00
37b9375389 allow that you dont need a resolution if amount > 30 2023-10-27 11:16:56 +00:00
082ad8f0b9 set color for status incomplete 2023-10-27 09:44:03 +00:00
1c6c850689 allow creating a bill without resolution 2023-10-27 09:29:40 +00:00
b12e7d8f16 update django to 4.2.6 2023-10-27 08:31:42 +00:00
93a5be82a8 update django-filter to 23.3 2023-10-27 08:28:12 +00:00
a7b1033a87 update django-environ to 0.11.2 2023-10-27 08:22:37 +00:00
b6cd9d5b16 fix button 2023-10-27 08:17:26 +00:00
9433a58a0b update assets 2023-10-27 07:54:32 +00:00
17741daeb9 fix migrations 2023-10-27 07:15:49 +00:00
403684d558 fix username: blank is True 2023-10-27 07:14:22 +00:00
dc1a5bc405 add finance migrations 2023-10-27 06:45:21 +00:00
49d904c49d add memer migrations 2023-10-27 06:45:07 +00:00
3dc5d43d21 add a new status incomplete 2023-10-27 06:35:48 +00:00
bde7b72d40 fix description and image. New member can be created after log in. 2023-10-27 06:32:06 +00:00
a290ba8c9f set nickname if a member is created 2023-10-27 06:17:40 +00:00
6a1b576bbe delete finance perm check 2023-10-25 19:34:50 +00:00
4a6be8f75e check if user has finance perm 2023-10-25 10:43:17 +00:00
5a1222187a add creating resolution and view of them 2023-10-10 11:01:45 +00:00
afa05afcc0 fix if there is no instance, it throws an error 2023-09-18 11:39:34 +00:00
76eba4392e add done page for bill created 2023-09-18 09:10:56 +00:00
3a7d87c3eb fix wording 2023-09-18 09:10:00 +00:00
c8fd414f8c add wiref, bill inline, total 2023-09-18 07:38:36 +00:00
faf80d59f0 add colored status 2023-09-05 14:49:58 +00:00
9f37ab1097 fix wording 2023-08-29 11:50:04 +00:00
d23b4ef87b fix "mehr/weniger anzeigen" button 2023-08-29 10:13:06 +00:00
63679973f7 Update Redesign to 2.0.0 - Switched to CSP safe 2023-08-29 10:06:48 +00:00
91c5cd9dfc now it works to add the hastag fachschaft 2023-08-28 16:29:19 +00:00
0616849a6d update django-ckeditor to 6.7.0 2023-08-22 20:34:56 +00:00
67917dd05c update django to 4.2.4 2023-08-22 20:28:06 +00:00
308461b0c0 delete migrations 2023-08-22 20:23:43 +00:00
047eac7b5c fix import 2023-08-22 20:23:02 +00:00
647544b460 black 2023-08-22 20:14:00 +00:00
7d2091b0a9 add new feature finance (submit bill) 2023-08-22 20:10:38 +00:00
eeeeaa50dc add new and update existing baseforms 2023-08-22 20:03:57 +00:00
35bae02f48 fix icon 2023-08-07 15:51:59 +00:00
51a233ce92 update assets 2023-08-02 10:14:46 +00:00
f4991b863d add migrations 2023-08-02 09:34:30 +00:00
59c546a035 change superuser to user with all perms 2023-08-01 23:17:06 +00:00
7abc6f1d0d add event place to album 2023-08-01 23:05:46 +00:00
3107cd0806 add order to jobs 2023-08-01 22:42:53 +00:00
61b68ec8ea change admin title 2023-08-01 21:32:47 +00:00
eb0b4af9d7 black formatting 2023-08-01 19:35:23 +00:00
0d17f30d72 update authentications 2023-08-01 16:02:01 +00:00
70b017af9e add helptext 2023-07-10 19:02:06 +00:00
3cfab5e13e delete big first letter 2023-07-02 23:15:44 +00:00
24ceef1c7c add links 2023-06-25 10:18:28 +00:00
3d12454700 add migrations 2023-06-21 12:52:16 +00:00
a6d2c43a6c update close button because of django 4.2 2023-06-21 12:50:39 +00:00
a3d5e28ccd deprecation in django 5.0 2023-06-21 12:49:56 +00:00
ecf2871ba8 update django to 4.2.2 2023-06-21 12:48:49 +00:00
db01cb3a9c change wording to "Angeheftet" 2023-06-21 11:12:48 +00:00
842c19ad65 update django-environ to 0.10.0 2023-06-21 11:08:20 +00:00
2a2b8909db update django-filter to 23.2 2023-06-21 11:06:53 +00:00
0fcead7454 update django-taggit to 4.0.0 2023-06-21 10:51:12 +00:00
d38a76a341 update easy-thumbnails to 2.8.5 2023-06-21 10:43:17 +00:00
cae5221581 update fontawesomefree to 6.4.0 2023-06-21 10:36:55 +00:00
503bbe8237 fix pycairo 2023-06-21 10:21:56 +00:00
97d0fa97a2 update xhtml2pdf to 0.2.11 2023-06-21 09:50:43 +00:00
2dfaf326f1 fix url 2023-06-20 08:51:18 +00:00
db0b3b3b41 fix clean functions 2023-06-20 08:47:29 +00:00
18c114a1c5 black format 2023-06-20 07:59:39 +00:00
c05993dcba create pad rework 2023-05-31 21:56:01 +02:00
19e272e9be add libraries for pycairo install 2023-05-31 21:33:01 +02:00
d921336ff9 search script 2023-05-14 20:08:52 +02:00
5c1d62c9f6 Fix gallery thumbnail creation 2023-03-23 19:43:00 +01:00
294bffdef4 requirements txt 2023-03-23 19:11:42 +01:00
478619c1dd authentications fix 2023-03-23 17:49:49 +00:00
c69a4469da format 2023-03-23 17:49:41 +00:00
cd8eb957ec search 2 2023-03-23 17:48:05 +00:00
ffd9281df7 legacy search 2023-03-23 17:47:23 +00:00
6f7eab8c38 set decimal places to 2 2023-02-09 10:26:59 +00:00
c5a67ad37c swap next and prev 2023-01-30 09:24:00 +00:00
0a0282cdfa change 'Bearbeiten' to 'Speichern' 2023-01-29 21:48:47 +00:00
3d854c0617 add csrf token 2023-01-29 21:41:22 +00:00
46836370ef code styling 2023-01-29 21:38:23 +00:00
69b8b926c7 jobs order by name 2023-01-29 21:35:21 +00:00
6a32504e59 Merge branch 'master' of https://git.fet.at/bofh/fet2020 2023-01-13 13:51:16 +00:00
ea567f5a89 fix extend with wrong html file 2023-01-13 10:27:45 +00:00
d4edec9a09 Merge branch 'master' of https://git.fet.at/bofh/fet2020 2023-01-12 17:16:38 +01:00
92ef3b3fae updated docker-compose.yml according to test 2023-01-12 17:05:57 +01:00
67dd93dd2b change code to bash 2023-01-12 11:39:31 +00:00
3c0810d9a9 add code formatting 2023-01-12 11:19:50 +00:00
a04e4018c8 sorted jobs in member profile 2023-01-12 11:18:57 +00:00
5b52470f87 fix set active 2023-01-12 10:48:52 +00:00
1fc063a378 ordering member 2023-01-12 03:25:59 +00:00
2622e82500 fix set active 2023-01-12 03:21:53 +00:00
3b9be918bf jobs in profile, order by job name 2023-01-12 00:53:11 +00:00
a44fc0bfcb fix templatetag 2023-01-12 00:06:23 +00:00
d85e81b184 disable infoBox 2023-01-10 17:34:54 +00:00
c32619b703 add password change as a button in admin view 2023-01-10 17:30:27 +00:00
2b3302d9c4 isort formatting then black formatting 2023-01-09 18:22:26 +00:00
eca6d68dc3 Reordering imports 2023-01-09 16:34:02 +00:00
771eaa3917 black formatting 2023-01-09 16:25:51 +00:00
b47aa54ffe add tag while creating a new fetmeeting 2023-01-09 11:56:28 +00:00
f42e47a650 job sidebar as a templatetag 2023-01-08 12:42:02 +00:00
274257ff58 publish project version 2023-01-08 10:28:51 +00:00
cd28dd177d black formatting 2023-01-08 00:09:46 +00:00
eba93d87b1 delete unused context 2023-01-07 23:03:37 +00:00
b5f274328f update path names 2023-01-07 12:26:24 +00:00
5a8d993cbb fix get_app_list 2023-01-07 11:43:34 +00:00
a2ae24d0ae add change password 2023-01-06 16:03:33 +00:00
0ee942e296 simplify authentication 2023-01-06 14:40:02 +00:00
7fb89158a9 change loginPage to LoginView 2023-01-06 13:20:35 +00:00
b48a817e8c update assets 2023-01-02 20:12:29 +00:00
e213f41bb7 show related posts when there are more than one. 2023-01-02 19:44:54 +00:00
af7dbe74f3 fix tags in posts 2023-01-02 19:44:18 +00:00
1ca5049a06 move head.html to base.html 2023-01-02 17:46:26 +00:00
8c8d53a238 reorder import 2023-01-02 17:45:53 +00:00
632a097a25 fix form method 2023-01-02 17:40:36 +00:00
641d435d4e add speed dial and shortcut to create fetmeeting 2023-01-02 17:40:06 +00:00
3793aa914c update show to DetailViews, add UpdateViews and CreateView 2023-01-02 17:38:43 +00:00
7ab97c91b7 remove fotos and change resolver in nginx conf 2023-01-01 14:27:43 +01:00
1a3f87ef9e redo the healthchecks in test.yml 2023-01-01 11:56:01 +01:00
851c10c274 healthcheck test tag 2022-12-31 14:57:43 +01:00
0e0aeee5f0 modified etherpad healthcheck timeout 2022-12-31 14:43:29 +01:00
7365009e0f fix mysql version 2022-12-29 15:13:58 +01:00
a803c97307 custom network 2022-12-23 10:11:59 +01:00
afe4235a8f restart test_containers 2022-12-23 09:02:41 +01:00
c8daeb043e test etherpad version fixed to n1.8.17 2022-12-22 22:15:52 +01:00
83debd3824 import slugify in tasks migratgion 2022-12-22 19:35:10 +01:00
9a7245294b Merge branch 'master' of https://git.fet.at/bofh/fet2020 2022-12-22 19:12:06 +01:00
78e5f03830 no public sql port 2022-12-22 19:10:40 +01:00
55df4f266a healthcheck for etherpad sql 2022-12-22 19:10:01 +01:00
b0dfe25ac5 update dependencies 2022-12-21 12:23:19 +00:00
e8a772ea7f create migration according to howto from Django homepage 2022-12-21 12:04:39 +00:00
077f70bf9f delete logging, add update_fields 2022-12-21 11:30:01 +00:00
b2573b398e add debug and delete time for tests 2022-12-19 17:33:29 +00:00
8007480ed7 delete debug stuffs 2022-12-19 17:17:15 +00:00
3de3e2780e fix length 2022-12-19 16:27:03 +00:00
c0f85896f0 xrange to range 2022-12-19 11:49:19 +01:00
593f9025a1 intent fixed 2022-12-19 11:20:48 +01:00
fe83d69453 tasks migration 2022-12-19 11:16:11 +01:00
3c54be75d6 chekc for past ids 2022-12-19 11:09:53 +01:00
9b0a2cd70c increase length of randomid 2022-12-19 10:44:56 +01:00
c10091a9c9 extend length of taskid 2022-12-19 10:24:36 +01:00
2a01717033 Merge branch 'master' of https://git.fet.at/bofh/fet2020 2022-12-19 09:30:56 +01:00
191ffc682f docker test mysql for fet2020 2022-12-18 15:29:58 +01:00
a3f9965d87 add logging 2022-12-17 22:06:20 +00:00
131b5580c4 change volumes 2022-12-17 20:37:06 +00:00
5d0a31d7f0 delete links and add ports 2022-12-14 15:02:57 +00:00
830c7b7616 add links to test 2022-12-14 14:24:36 +00:00
96d78f0f32 fixing etherpad not getting healthy 2022-12-10 11:07:15 +01:00
6a3354c5c2 fix docker compose 2022-11-29 22:03:12 +00:00
9f7e4f3659 fix docker compose 2022-11-29 21:52:50 +00:00
2b52e6433b fix docker compose 2022-11-29 21:50:12 +00:00
df7b804b2b fix docker compose 2022-11-29 21:24:24 +00:00
3e8ffe058d fix docker compose 2022-11-29 21:05:01 +00:00
ee2bbdb4b8 fix docker compose 2022-11-29 20:55:16 +00:00
25f60c5dbf fix migration 2022-11-29 20:24:56 +00:00
d85728858f remove flaskfetfotos 2022-11-29 18:56:27 +00:00
081d612bff fix member url 2022-11-29 17:12:50 +00:00
dcdbb6ea68 add button to admin 2022-11-29 16:36:34 +00:00
35453ffe8b fix missing access to topic 2022-11-29 16:14:24 +00:00
66b5bc1603 update assets 2022-11-29 13:10:05 +00:00
9a59727124 fix PopUpNav 2022-11-29 13:07:54 +00:00
02130df21f search only for authenticated users 2022-11-29 12:48:51 +00:00
a8c52bdf7b fix alpine-js stuffs blocked by csp 2022-11-29 10:06:04 +00:00
a62ec0c2cb fix sitemaps 2022-11-28 10:17:07 +00:00
75cad5cc4c add alpine-js stuffs blocked by csp 2022-11-24 17:17:26 +00:00
7a5b888152 fix icon 2022-11-24 16:24:00 +00:00
e333bae8ca update assets part 7 2022-11-23 08:58:02 +00:00
608277f7de update assets part 6 2022-11-23 08:57:49 +00:00
c83e9fb93b update assets part 5 2022-11-23 08:57:11 +00:00
c609e7de5b update assets part 4 2022-11-23 08:56:53 +00:00
e019ec9965 update assets part 3 2022-11-23 08:55:59 +00:00
0470900951 update assets part 2 2022-11-23 08:55:21 +00:00
c2f3feb9b7 update assets part 1 2022-11-23 08:54:40 +00:00
f75cdcdae7 update blueimp-gallery to 3.4.0 2022-11-23 08:45:11 +00:00
dc3bdb59a3 update fontawesomefree to 6.2.0 2022-11-23 08:40:30 +00:00
eef6b59f9b fix migration 2022-11-21 21:57:21 +00:00
bc69f366df add dark mode button 2022-11-21 19:35:43 +00:00
916e7caaa5 change wording 2022-11-21 13:45:57 +00:00
76804d6c2a change jobs to section and blackboard to jobs 2022-11-21 13:43:26 +00:00
881eec0ec7 fix symbol 2022-11-21 13:09:47 +00:00
44e9dddf23 update Redesign to v1.2.0-dev 2022-11-21 11:56:52 +00:00
8ce674e2de merge branch 'master' 2022-11-21 10:28:38 +00:00
53ca22f003 update django-taggit to 3.1.0 2022-11-21 10:25:28 +00:00
f55b67e20f fix mapping for docker test 2022-11-20 22:29:09 +01:00
94c8fb7326 test dockerfile 2022-11-20 21:55:25 +01:00
9018fda102 fix alpine-js stuffs blocked by csp 2022-11-20 19:09:45 +00:00
ee357cae28 update test docker compose 2022-11-17 21:00:14 +01:00
f48c6439d0 add migration 2022-11-05 08:36:23 +00:00
f2e45d85cc fix migration 2022-10-21 08:35:49 +00:00
77d6536c61 delete unused imports and _-translation 2022-10-21 08:10:56 +00:00
6d72c7a2d3 add exception 2022-10-21 07:54:57 +00:00
8dfa69cf8d add search as a app 2022-10-17 09:44:26 +00:00
ce7529e871 delete local app 2022-10-17 09:43:30 +00:00
7dd6a91658 update django to 4.1.2 2022-10-17 08:17:36 +00:00
0cef42afbe update djangorestframework to 3.14.0 2022-10-17 07:28:38 +00:00
9149a6c690 update django-ckeditor to 6.5.1 2022-10-17 07:21:04 +00:00
7503 changed files with 649255 additions and 211450 deletions

View File

@@ -1,6 +0,0 @@
DEBUG=FALSE
HOST_NAME=uat1.2020.fet.at
SECRET_KEY=235t3groing43qo4ntgigon43qgi3q4gong
MYSQL_USER=user
MYSQL_PASSWORD=hgu
MYSQL_PORT=3306

11
.gitignore vendored
View File

@@ -1,7 +1,6 @@
.env/*
*.pyc
*_design1
fet2020/files/*
fet2020/.env/*
*.sqlite3
.theia/*
@@ -11,4 +10,12 @@ run
*.pid
*~
APIKEY.txt
tmp
tmp
.ruff_cache
.venv
etherpad
files
flowbite
gallery
tailwind
whoosh_index

View File

@@ -1,17 +0,0 @@
{
"folders": [
{
"path": "fet2020"
}
],
"settings": {
"launch": {},
"python.linting.flake8Enabled": true,
"python.linting.banditEnabled": true,
"python.testing.pytestEnabled": true,
"python.linting.flake8Args": [
"--max-line-length=100"
]
}
}

View File

@@ -5,13 +5,43 @@ RUN python -m venv /opt/venv
ENV PATH="/opt/venv/bin:$PATH"
RUN apk add --no-cache --virtual .build-deps ca-certificates gcc linux-headers \
musl-dev jpeg-dev zlib-dev libffi-dev mysql mariadb-dev freetype-dev\
&& pip install --upgrade pip
musl-dev \
jpeg-dev \
zlib-dev \
libffi-dev \
mysql \
mariadb-dev \
freetype-dev \
# install for pymupdf
# && apk add --no-cache \
# libffi-dev \
# zlib-dev \
# freetype-dev \
# make \
# build-base \
# gcc \
# jbig2dec \
# jpeg-dev \
# harfbuzz-dev \
# libc-dev \
# mupdf-dev \
# musl-dev \
# openjpeg-dev \
# swig \
# && ln -s /usr/lib/libjbig2dec.so.0 /usr/lib/libjbig2dec.so \
# && pip install pymupdf==1.23.18 \
# upgrade pip
&& pip install --upgrade pip
# setting for pymupdf
# ENV PYMUPDF_SETUP_MUPDF_TESSERACT="0"
COPY ./fet2020/requirements.txt /app/requirements.txt
RUN pip install -r requirements.txt
# Remove virtual environment dependencies
# RUN apk del .builddeps
FROM tiangolo/uwsgi-nginx:python3.8-alpine

213
Readme.md
View File

@@ -1,61 +1,152 @@
##Fet 2020 Django Project
Diese Webseite ist im Jahr 2020 entwickelt worden. Wir haben dazu einige Designentscheidungen getroffen:
1. Zunächst auf die externen Kernfunktionen fokusieren
2. Python+Django nutzen weil:
* Wir Python mögen
* Das Framework uns freiheit gibt zB die Mitglieder Daten entsprechend abzubilden
* Das Design unabhängig von der Funktion bleibt
* und einiges mehr
3. Als Kernfunktionen festgelegt wurden anfangs:
* Neuigkeiten posten
* FET Sitzungen ankündigen
* Etherpad für Agenda und Protokoll
* Informationen zu Mitgliedern anzeigen
4. Unter dem Eindruck eines Jahres des Lockdown wurde zusätzlich hinzugefügt
* Ein virtuelles Schwarzesbrett
* Eine virtuelle Aufgabenliste
### Ablage und Entwicklung
Der Master liegt auf dem virtuellen git Server und kann wie folgt geholt werden:
```bash
git clone https://git.fet.at/bofh/fet2020
```
### Deployment
{{docker-compose.yml}}
<code>
docker-compose up
</code>
### Command Befehle
Erstellt die fehlenden Thumbs für die Alben in der Galerie:
<code>
python3 fet2020/manage.py create_thumbs
</code>
Erstellt alle Searchindexes neu:
<code>
python3 fet2020/manage.py rebuild_index
</code>
Aktualisiert alle Searchindexes:
<code>
python3 fet2020/manage.py update_index
</code>
Fügt alle Cronjobs in diesem Projekt hinzu:
<code>
python3 fet2020/manage.py crontab add
</code>
Fügt alle Staticfiles in die Assets hinzu:
<code>
python3 fet2020/manage.py collectstatic
</code>
Überprüft, ob die Software bereit für die Produktion ist.
<code>
python3 fet2020/manage.py check --deploy
</code>
# Fet 2020 Django Project
Diese Webseite ist im Jahr 2020 entwickelt worden. Wir haben dazu einige Designentscheidungen getroffen:
1. Zunächst auf die externen Kernfunktionen fokussieren
2. Python + Django nutzen weil:
* wir Python mögen
* das Framework uns die Freiheit gibt, zB die Mitglieder Daten entsprechend abzubilden
* das Design unabhängig von der Funktion bleibt
* und einiges mehr
3. Als Kernfunktionen festgelegt wurden anfangs:
* Neuigkeiten posten
* FET Sitzungen ankündigen
* Etherpad für Agenda und Protokoll
* Informationen zu Mitgliedern anzeigen
4. Unter dem Eindruck eines Jahres des Lockdown wurde zusätzlich hinzugefügt
* Ein virtuelles Schwarzesbrett
## Development
The main branch is hosted on the FET git server. Clone the repository using the following command:
```bash
git clone https://git.fet.at/bofh/fet2020
```
## Debug
If you are developing on Windows, install Visual Studio Code and Docker Desktop.
Add a local user/member for login because the project is not connected to FET LDAP in dev mode:
```bash
python manage.py createsuperuser
```
### Python version
View all python versions:
```bash
uv python list
```
Installing Python executables:
```bash
uv python install $(.python-version) --default
```
Update the following files if the python version is increased:
* .python-version
* pyproject.toml
* run-pre-commit.sh
## Deployment
### Docker image for django
Makemigrations:
```bash
python fet2020/manage.py makemigrations blackboard core finance gallery members posts rental
```
```bash
python fet2020/manage.py makemigrations intern
```
Add all static files to the assets:
```bash
python fet2020/manage.py collectstatic
```
Check if the project is for deployment:
```bash
python fet2020/manage.py check --deploy
```
Build the docker image of django project:
```bash
docker build -t django-image -f fet2020/Dockerfile ./fet2020
```
### Docker image for nginx
Build the docker image of nginx:
```bash
docker build -t django-nginx-image -f nginx/Dockerfile ./nginx
```
### Start docker container
Build the docker containers:
```bash
docker compose -f docker-compose.yml up -d
```
Remove all unused docker images older than 24 hours:
```bash
docker image prune -a --filter "until=24h"
```
## Other Useful Commands
Please use the command carefully! Remove all unused docker volumes:
```bash
docker volume prune -a
```
Rebuilds all search indexes:
```bash
python3 fet2020/manage.py rebuild_index
```
Updates all search indexes:
```bash
python3 fet2020/manage.py update_index
```
## TODO
ckeditor -> django-prose-editor
## Version History
2.2.0
* Add rental
2.1.0
* Add finance system
2.0.0
* Update the homepage design
* Add intern
1.0.0
* First release of the new homepage

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@@ -1,23 +1,23 @@
MIT License
Copyright © 2013 Sebastian Tschan, https://blueimp.net
Swipe implementation based on: https://github.com/thebird/Swipe
Copyright © 2013 Brad Birdsall, https://github.com/thebird
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
MIT License
Copyright © 2013 Sebastian Tschan, https://blueimp.net
Swipe implementation based on: https://github.com/thebird/Swipe
Copyright © 2013 Brad Birdsall, https://github.com/thebird
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@@ -0,0 +1,3 @@
#!/bin/sh
cd "$(dirname "$0")/.."
cp node_modules/jquery/dist/jquery.js js/vendor/

View File

@@ -1,97 +1,97 @@
@charset "UTF-8";
/*
* blueimp Gallery Indicator CSS
* https://github.com/blueimp/Gallery
*
* Copyright 2013, Sebastian Tschan
* https://blueimp.net
*
* Licensed under the MIT license:
* https://opensource.org/licenses/MIT
*/
.blueimp-gallery > .indicator {
position: absolute;
top: auto;
right: 15px;
bottom: 15px;
left: 15px;
margin: 0 40px;
padding: 0;
list-style: none;
text-align: center;
line-height: 10px;
display: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.blueimp-gallery > .indicator > li {
display: inline-block;
position: relative;
width: 9px;
height: 9px;
margin: 6px 3px 0 3px;
-webkit-box-sizing: content-box;
-moz-box-sizing: content-box;
box-sizing: content-box;
border: 1px solid transparent;
background: #ccc;
background: rgba(255, 255, 255, 0.25) center no-repeat;
border-radius: 5px;
box-shadow: 0 0 2px #000;
opacity: 0.5;
cursor: pointer;
}
/* IE7 fixes */
* + html .blueimp-gallery > .indicator > li {
display: inline;
}
.blueimp-gallery > .indicator > li:hover,
.blueimp-gallery > .indicator > .active {
background-color: #fff;
border-color: #fff;
opacity: 1;
}
.blueimp-gallery > .indicator > li:after {
opacity: 0;
display: block;
position: absolute;
content: '';
top: -5em;
left: 4px;
width: 75px;
height: 75px;
transition: transform 600ms ease-out, opacity 400ms ease-out;
transform: translateX(-50%) translateY(0) translateZ(0px);
pointer-events: none;
}
.blueimp-gallery > .indicator > li:hover:after {
opacity: 1;
border-radius: 50%;
background: inherit;
transform: translateX(-50%) translateY(-5px) translateZ(0px);
}
.blueimp-gallery > .indicator > .active:after {
display: none;
}
.blueimp-gallery-controls > .indicator {
display: block;
/* Fix z-index issues (controls behind slide element) on Android: */
-webkit-transform: translateZ(0);
-moz-transform: translateZ(0);
-ms-transform: translateZ(0);
-o-transform: translateZ(0);
transform: translateZ(0);
}
.blueimp-gallery-single > .indicator {
display: none;
}
@charset "UTF-8";
/*
* blueimp Gallery Indicator CSS
* https://github.com/blueimp/Gallery
*
* Copyright 2013, Sebastian Tschan
* https://blueimp.net
*
* Licensed under the MIT license:
* https://opensource.org/licenses/MIT
*/
.blueimp-gallery > .indicator {
position: absolute;
top: auto;
right: 15px;
bottom: 15px;
left: 15px;
margin: 0 40px;
padding: 0;
list-style: none;
text-align: center;
line-height: 10px;
display: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.blueimp-gallery > .indicator > li {
display: inline-block;
position: relative;
width: 9px;
height: 9px;
margin: 6px 3px 0 3px;
-webkit-box-sizing: content-box;
-moz-box-sizing: content-box;
box-sizing: content-box;
border: 1px solid transparent;
background: #ccc;
background: rgba(255, 255, 255, 0.25) center no-repeat;
border-radius: 5px;
box-shadow: 0 0 2px #000;
opacity: 0.5;
cursor: pointer;
}
/* IE7 fixes */
* + html .blueimp-gallery > .indicator > li {
display: inline;
}
.blueimp-gallery > .indicator > li:hover,
.blueimp-gallery > .indicator > .active {
background-color: #fff;
border-color: #fff;
opacity: 1;
}
.blueimp-gallery > .indicator > li:after {
opacity: 0;
display: block;
position: absolute;
content: '';
top: -5em;
left: 4px;
width: 75px;
height: 75px;
transition: transform 600ms ease-out, opacity 400ms ease-out;
transform: translateX(-50%) translateY(0) translateZ(0px);
pointer-events: none;
}
.blueimp-gallery > .indicator > li:hover:after {
opacity: 1;
border-radius: 50%;
background: inherit;
transform: translateX(-50%) translateY(-5px) translateZ(0px);
}
.blueimp-gallery > .indicator > .active:after {
display: none;
}
.blueimp-gallery-controls > .indicator {
display: block;
/* Fix z-index issues (controls behind slide element) on Android: */
-webkit-transform: translateZ(0);
-moz-transform: translateZ(0);
-ms-transform: translateZ(0);
-o-transform: translateZ(0);
transform: translateZ(0);
}
.blueimp-gallery-single > .indicator {
display: none;
}

View File

@@ -1,69 +1,69 @@
@charset "UTF-8";
/*
* blueimp Gallery Video Factory CSS
* https://github.com/blueimp/Gallery
*
* Copyright 2013, Sebastian Tschan
* https://blueimp.net
*
* Licensed under the MIT license:
* https://opensource.org/licenses/MIT
*/
.blueimp-gallery > .slides > .slide > .video-content > video,
.blueimp-gallery > .slides > .slide > .video-content > iframe,
.blueimp-gallery > .slides > .slide > .video-content > .video-cover {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border: none;
}
.blueimp-gallery > .slides > .slide > .video-content > .video-cover {
background: center no-repeat;
background-size: contain;
}
.blueimp-gallery > .slides > .slide > .video-iframe > .video-cover {
background-color: #000;
background-color: rgba(0, 0, 0, 0.7);
}
.blueimp-gallery > .slides > .slide > .video-content > .video-play {
position: absolute;
top: 50%;
right: 0;
left: 0;
margin: -64px auto 0;
width: 128px;
height: 128px;
background: url(../img/video-play.png) center no-repeat;
opacity: 0.8;
cursor: pointer;
}
.blueimp-gallery-svgasimg > .slides > .slide > .video-content > .video-play {
background-image: url(../img/video-play.svg);
}
.blueimp-gallery > .slides > .slide > .video-playing > .video-play,
.blueimp-gallery > .slides > .slide > .video-playing > .video-cover {
display: none;
}
.blueimp-gallery > .slides > .slide > .video-loading > .video-play {
background: url(../img/loading.gif) center no-repeat;
background-size: 64px 64px;
}
.blueimp-gallery-smil > .slides > .slide > .video-loading > .video-play {
background-image: url(../img/loading.svg);
}
/* IE7 fixes */
* + html .blueimp-gallery > .slides > .slide > .video-content {
height: 100%;
}
* + html .blueimp-gallery > .slides > .slide > .video-content > .video-play {
left: 50%;
margin-left: -64px;
}
.blueimp-gallery > .slides > .slide > .video-content > .video-play:hover {
opacity: 1;
}
@charset "UTF-8";
/*
* blueimp Gallery Video Factory CSS
* https://github.com/blueimp/Gallery
*
* Copyright 2013, Sebastian Tschan
* https://blueimp.net
*
* Licensed under the MIT license:
* https://opensource.org/licenses/MIT
*/
.blueimp-gallery > .slides > .slide > .video-content > video,
.blueimp-gallery > .slides > .slide > .video-content > iframe,
.blueimp-gallery > .slides > .slide > .video-content > .video-cover {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border: none;
}
.blueimp-gallery > .slides > .slide > .video-content > .video-cover {
background: center no-repeat;
background-size: contain;
}
.blueimp-gallery > .slides > .slide > .video-iframe > .video-cover {
background-color: #000;
background-color: rgba(0, 0, 0, 0.7);
}
.blueimp-gallery > .slides > .slide > .video-content > .video-play {
position: absolute;
top: 50%;
right: 0;
left: 0;
margin: -64px auto 0;
width: 128px;
height: 128px;
background: url(../img/video-play.png) center no-repeat;
opacity: 0.8;
cursor: pointer;
}
.blueimp-gallery-svgasimg > .slides > .slide > .video-content > .video-play {
background-image: url(../img/video-play.svg);
}
.blueimp-gallery > .slides > .slide > .video-playing > .video-play,
.blueimp-gallery > .slides > .slide > .video-playing > .video-cover {
display: none;
}
.blueimp-gallery > .slides > .slide > .video-loading > .video-play {
background: url(../img/loading.gif) center no-repeat;
background-size: 64px 64px;
}
.blueimp-gallery-smil > .slides > .slide > .video-loading > .video-play {
background-image: url(../img/loading.svg);
}
/* IE7 fixes */
* + html .blueimp-gallery > .slides > .slide > .video-content {
height: 100%;
}
* + html .blueimp-gallery > .slides > .slide > .video-content > .video-play {
left: 50%;
margin-left: -64px;
}
.blueimp-gallery > .slides > .slide > .video-content > .video-play:hover {
opacity: 1;
}

View File

@@ -1,249 +1,249 @@
@charset "UTF-8";
/*
* blueimp Gallery CSS
* https://github.com/blueimp/Gallery
*
* Copyright 2013, Sebastian Tschan
* https://blueimp.net
*
* Licensed under the MIT license:
* https://opensource.org/licenses/MIT
*/
.blueimp-gallery,
.blueimp-gallery > .slides > .slide > .slide-content,
.blueimp-gallery > .slides > .slide > .slide-content > img {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
-webkit-transition: opacity 0.2s linear;
-moz-transition: opacity 0.2s linear;
-ms-transition: opacity 0.2s linear;
-o-transition: opacity 0.2s linear;
transition: opacity 0.2s linear;
/* Prevent artifacts in Mozilla Firefox: */
backface-visibility: hidden;
-moz-backface-visibility: hidden;
}
.blueimp-gallery > .slides > .slide > .slide-content,
.blueimp-gallery > .slides > .slide > .slide-content > img {
margin: auto;
width: auto;
height: auto;
max-width: 100%;
max-height: 100%;
opacity: 1;
}
.blueimp-gallery {
position: fixed;
z-index: 999999;
overflow: hidden;
background: #000;
opacity: 0;
display: none;
direction: ltr;
-ms-touch-action: pinch-zoom;
touch-action: pinch-zoom;
}
.blueimp-gallery-carousel {
position: relative;
z-index: auto;
margin: 1em auto;
/* Set the carousel width/height ratio to 16/9: */
padding-bottom: 56.25%;
box-shadow: 0 0 4px rgba(0, 0, 0, 0.1);
-ms-touch-action: pan-y pinch-zoom;
touch-action: pan-y pinch-zoom;
display: block;
}
.blueimp-gallery-display {
display: block;
opacity: 1;
}
.blueimp-gallery > .slides {
position: relative;
height: 100%;
overflow: hidden;
}
.blueimp-gallery-carousel > .slides {
position: absolute;
}
.blueimp-gallery > .slides > .slide {
visibility: hidden;
position: relative;
float: left;
height: 100%;
text-align: center;
-webkit-transition-timing-function: cubic-bezier(0.645, 0.045, 0.355, 1);
-moz-transition-timing-function: cubic-bezier(0.645, 0.045, 0.355, 1);
-ms-transition-timing-function: cubic-bezier(0.645, 0.045, 0.355, 1);
-o-transition-timing-function: cubic-bezier(0.645, 0.045, 0.355, 1);
transition-timing-function: cubic-bezier(0.645, 0.045, 0.355, 1);
}
.blueimp-gallery > .slides > .slide-prev,
.blueimp-gallery > .slides > .slide-active,
.blueimp-gallery > .slides > .slide-next {
visibility: visible;
}
.blueimp-gallery > .slides > .slide-loading {
background: url(../img/loading.gif) center no-repeat;
background-size: 64px 64px;
}
.blueimp-gallery-smil > .slides > .slide-loading {
background-image: url(../img/loading.svg);
}
.blueimp-gallery > .slides > .slide-loading > .slide-content {
opacity: 0;
}
.blueimp-gallery > .slides > .slide-error {
background: url(../img/error.png) center no-repeat;
}
.blueimp-gallery-svgasimg > .slides > .slide-error {
background-image: url(../img/error.svg);
}
.blueimp-gallery > .slides > .slide-error > .slide-content {
display: none;
}
.blueimp-gallery-display > .prev,
.blueimp-gallery-display > .next {
position: absolute;
top: 50%;
left: 15px;
width: 8px;
height: 20px;
padding: 10px 14px 10px 18px;
margin-top: -23px;
-webkit-box-sizing: content-box;
-moz-box-sizing: content-box;
box-sizing: content-box;
background: #222 url(../img/prev.png) center no-repeat;
background-color: rgba(0, 0, 0, 0.5);
border: 3px solid #fff;
-webkit-border-radius: 30px;
-moz-border-radius: 30px;
border-radius: 30px;
opacity: 0.5;
cursor: pointer;
display: none;
}
.blueimp-gallery-display > .next {
right: 15px;
left: auto;
background-image: url(../img/next.png);
}
.blueimp-gallery-svgasimg > .prev {
background-image: url(../img/prev.svg);
}
.blueimp-gallery-svgasimg > .next {
background-image: url(../img/next.svg);
}
.blueimp-gallery-display > .close {
position: absolute;
top: 15px;
right: 15px;
width: 30px;
height: 30px;
background: url(../img/close.png) center no-repeat;
opacity: 0.8;
cursor: pointer;
display: none;
}
.blueimp-gallery-svgasimg > .close {
background-image: url(../img/close.svg);
}
.blueimp-gallery > .title {
position: absolute;
top: 15px;
left: 15px;
margin: 0 60px 0 0;
font-size: 20px;
line-height: 30px;
color: #fff;
text-shadow: 0 0 2px #000;
opacity: 0.8;
display: none;
}
.blueimp-gallery-display > .play-pause {
position: absolute;
right: 15px;
bottom: 15px;
width: 30px;
height: 30px;
background: url(../img/play-pause.png) 0 0 no-repeat;
cursor: pointer;
opacity: 0.5;
display: none;
}
.blueimp-gallery-svgasimg > .play-pause {
background-image: url(../img/play-pause.svg);
}
.blueimp-gallery-playing > .play-pause {
background-position: -30px 0;
}
.blueimp-gallery-controls > .prev,
.blueimp-gallery-controls > .next,
.blueimp-gallery-controls > .close,
.blueimp-gallery-controls > .title,
.blueimp-gallery-controls > .play-pause {
display: block;
/* Fix z-index issues (controls behind slide element) on Android: */
-webkit-transform: translateZ(0);
-moz-transform: translateZ(0);
-ms-transform: translateZ(0);
-o-transform: translateZ(0);
transform: translateZ(0);
}
.blueimp-gallery-single > .prev,
.blueimp-gallery-left > .prev,
.blueimp-gallery-single > .next,
.blueimp-gallery-right > .next,
.blueimp-gallery-single > .play-pause {
display: none;
}
.blueimp-gallery > .slides > .slide > .slide-content,
.blueimp-gallery > .prev,
.blueimp-gallery > .next,
.blueimp-gallery > .close,
.blueimp-gallery > .play-pause {
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.blueimp-gallery > .prev:hover,
.blueimp-gallery > .next:hover,
.blueimp-gallery > .close:hover,
.blueimp-gallery > .title:hover,
.blueimp-gallery > .play-pause:hover {
color: #fff;
opacity: 1;
}
/* IE7 fixes */
* + html .blueimp-gallery > .slides > .slide {
min-height: 300px;
}
* + html .blueimp-gallery > .slides > .slide > .slide-content {
position: relative;
}
* + html .blueimp-gallery > .slides > .slide > .slide-content > img {
position: relative;
}
@supports (object-fit: contain) {
.blueimp-gallery-contain > .slides > .slide > .slide-content,
.blueimp-gallery-contain > .slides > .slide > .slide-content > img {
width: 100%;
height: 100%;
object-fit: contain;
}
}
@media (prefers-color-scheme: light) {
.blueimp-gallery-carousel {
background: #fff;
}
}
@charset "UTF-8";
/*
* blueimp Gallery CSS
* https://github.com/blueimp/Gallery
*
* Copyright 2013, Sebastian Tschan
* https://blueimp.net
*
* Licensed under the MIT license:
* https://opensource.org/licenses/MIT
*/
.blueimp-gallery,
.blueimp-gallery > .slides > .slide > .slide-content,
.blueimp-gallery > .slides > .slide > .slide-content > img {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
-webkit-transition: opacity 0.2s linear;
-moz-transition: opacity 0.2s linear;
-ms-transition: opacity 0.2s linear;
-o-transition: opacity 0.2s linear;
transition: opacity 0.2s linear;
/* Prevent artifacts in Mozilla Firefox: */
backface-visibility: hidden;
-moz-backface-visibility: hidden;
}
.blueimp-gallery > .slides > .slide > .slide-content,
.blueimp-gallery > .slides > .slide > .slide-content > img {
margin: auto;
width: auto;
height: auto;
max-width: 100%;
max-height: 100%;
opacity: 1;
}
.blueimp-gallery {
position: fixed;
z-index: 999999;
overflow: hidden;
background: #000;
opacity: 0;
display: none;
direction: ltr;
-ms-touch-action: pinch-zoom;
touch-action: pinch-zoom;
}
.blueimp-gallery-carousel {
position: relative;
z-index: auto;
margin: 1em auto;
/* Set the carousel width/height ratio to 16/9: */
padding-bottom: 56.25%;
box-shadow: 0 0 4px rgba(0, 0, 0, 0.1);
-ms-touch-action: pan-y pinch-zoom;
touch-action: pan-y pinch-zoom;
display: block;
}
.blueimp-gallery-display {
display: block;
opacity: 1;
}
.blueimp-gallery > .slides {
position: relative;
height: 100%;
overflow: hidden;
}
.blueimp-gallery-carousel > .slides {
position: absolute;
}
.blueimp-gallery > .slides > .slide {
visibility: hidden;
position: relative;
float: left;
height: 100%;
text-align: center;
-webkit-transition-timing-function: cubic-bezier(0.645, 0.045, 0.355, 1);
-moz-transition-timing-function: cubic-bezier(0.645, 0.045, 0.355, 1);
-ms-transition-timing-function: cubic-bezier(0.645, 0.045, 0.355, 1);
-o-transition-timing-function: cubic-bezier(0.645, 0.045, 0.355, 1);
transition-timing-function: cubic-bezier(0.645, 0.045, 0.355, 1);
}
.blueimp-gallery > .slides > .slide-prev,
.blueimp-gallery > .slides > .slide-active,
.blueimp-gallery > .slides > .slide-next {
visibility: visible;
}
.blueimp-gallery > .slides > .slide-loading {
background: url(../img/loading.gif) center no-repeat;
background-size: 64px 64px;
}
.blueimp-gallery-smil > .slides > .slide-loading {
background-image: url(../img/loading.svg);
}
.blueimp-gallery > .slides > .slide-loading > .slide-content {
opacity: 0;
}
.blueimp-gallery > .slides > .slide-error {
background: url(../img/error.png) center no-repeat;
}
.blueimp-gallery-svgasimg > .slides > .slide-error {
background-image: url(../img/error.svg);
}
.blueimp-gallery > .slides > .slide-error > .slide-content {
display: none;
}
.blueimp-gallery-display > .prev,
.blueimp-gallery-display > .next {
position: absolute;
top: 50%;
left: 15px;
width: 8px;
height: 20px;
padding: 10px 14px 10px 18px;
margin-top: -23px;
-webkit-box-sizing: content-box;
-moz-box-sizing: content-box;
box-sizing: content-box;
background: #222 url(../img/prev.png) center no-repeat;
background-color: rgba(0, 0, 0, 0.5);
border: 3px solid #fff;
-webkit-border-radius: 30px;
-moz-border-radius: 30px;
border-radius: 30px;
opacity: 0.5;
cursor: pointer;
display: none;
}
.blueimp-gallery-display > .next {
right: 15px;
left: auto;
background-image: url(../img/next.png);
}
.blueimp-gallery-svgasimg > .prev {
background-image: url(../img/prev.svg);
}
.blueimp-gallery-svgasimg > .next {
background-image: url(../img/next.svg);
}
.blueimp-gallery-display > .close {
position: absolute;
top: 15px;
right: 15px;
width: 30px;
height: 30px;
background: url(../img/close.png) center no-repeat;
opacity: 0.8;
cursor: pointer;
display: none;
}
.blueimp-gallery-svgasimg > .close {
background-image: url(../img/close.svg);
}
.blueimp-gallery > .title {
position: absolute;
top: 15px;
left: 15px;
margin: 0 60px 0 0;
font-size: 20px;
line-height: 30px;
color: #fff;
text-shadow: 0 0 2px #000;
opacity: 0.8;
display: none;
}
.blueimp-gallery-display > .play-pause {
position: absolute;
right: 15px;
bottom: 15px;
width: 30px;
height: 30px;
background: url(../img/play-pause.png) 0 0 no-repeat;
cursor: pointer;
opacity: 0.5;
display: none;
}
.blueimp-gallery-svgasimg > .play-pause {
background-image: url(../img/play-pause.svg);
}
.blueimp-gallery-playing > .play-pause {
background-position: -30px 0;
}
.blueimp-gallery-controls > .prev,
.blueimp-gallery-controls > .next,
.blueimp-gallery-controls > .close,
.blueimp-gallery-controls > .title,
.blueimp-gallery-controls > .play-pause {
display: block;
/* Fix z-index issues (controls behind slide element) on Android: */
-webkit-transform: translateZ(0);
-moz-transform: translateZ(0);
-ms-transform: translateZ(0);
-o-transform: translateZ(0);
transform: translateZ(0);
}
.blueimp-gallery-single > .prev,
.blueimp-gallery-left > .prev,
.blueimp-gallery-single > .next,
.blueimp-gallery-right > .next,
.blueimp-gallery-single > .play-pause {
display: none;
}
.blueimp-gallery > .slides > .slide > .slide-content,
.blueimp-gallery > .prev,
.blueimp-gallery > .next,
.blueimp-gallery > .close,
.blueimp-gallery > .play-pause {
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.blueimp-gallery > .prev:hover,
.blueimp-gallery > .next:hover,
.blueimp-gallery > .close:hover,
.blueimp-gallery > .title:hover,
.blueimp-gallery > .play-pause:hover {
color: #fff;
opacity: 1;
}
/* IE7 fixes */
* + html .blueimp-gallery > .slides > .slide {
min-height: 300px;
}
* + html .blueimp-gallery > .slides > .slide > .slide-content {
position: relative;
}
* + html .blueimp-gallery > .slides > .slide > .slide-content > img {
position: relative;
}
@supports (object-fit: contain) {
.blueimp-gallery-contain > .slides > .slide > .slide-content,
.blueimp-gallery-contain > .slides > .slide > .slide-content > img {
width: 100%;
height: 100%;
object-fit: contain;
}
}
@media (prefers-color-scheme: light) {
.blueimp-gallery-carousel {
background: #fff;
}
}

File diff suppressed because one or more lines are too long

View File

@@ -1 +1 @@
{"version":3,"sources":["blueimp-gallery.css","blueimp-gallery-indicator.css","blueimp-gallery-video.css"],"names":[],"mappings":"iBAYA,iBACA,+CACA,mDACE,SAAU,SACV,IAAK,EACL,MAAO,EACP,OAAQ,EACR,KAAM,EACN,mBAAoB,QAAQ,IAAK,OACjC,gBAAiB,QAAQ,IAAK,OAC9B,eAAgB,QAAQ,IAAK,OAC7B,cAAe,QAAQ,IAAK,OAC5B,WAAY,QAAQ,IAAK,OAEzB,oBAAqB,OACrB,yBAA0B,OAE5B,+CACA,mDACE,OAAQ,KACR,MAAO,KACP,OAAQ,KACR,UAAW,KACX,WAAY,KACZ,QAAS,EAEX,iBACE,SAAU,MACV,QAAS,OACT,SAAU,OACV,WAAY,KACZ,QAAS,EACT,QAAS,KACT,UAAW,IACX,iBAAkB,WAClB,aAAc,WAEhB,0BACE,SAAU,SACV,QAAS,KACT,OAAQ,IAAI,KAEZ,eAAgB,OAChB,WAAY,EAAE,EAAE,IAAI,eACpB,iBAAkB,MAAM,WACxB,aAAc,MAAM,WACpB,QAAS,MAEX,yBACE,QAAS,MACT,QAAS,EAEX,yBACE,SAAU,SACV,OAAQ,KACR,SAAU,OAEZ,kCACE,SAAU,SAEZ,gCACE,WAAY,OACZ,SAAU,SACV,MAAO,KACP,OAAQ,KACR,WAAY,OACZ,mCAAoC,+BACpC,gCAAiC,+BACjC,+BAAgC,+BAChC,8BAA+B,+BAC/B,2BAA4B,+BAG9B,uCACA,qCAFA,qCAGE,WAAY,QAEd,wCACE,WAAY,wBAAwB,OAAO,UAC3C,gBAAiB,KAAK,KAExB,6CACE,iBAAkB,wBAEpB,uDACE,QAAS,EAEX,sCACE,WAAY,sBAAsB,OAAO,UAE3C,+CACE,iBAAkB,sBAEpB,qDACE,QAAS,KAGX,+BADA,+BAEE,SAAU,SACV,IAAK,IACL,KAAM,KACN,MAAO,IACP,OAAQ,KACR,QAAS,KAAK,KAAK,KAAK,KACxB,WAAY,MACZ,mBAAoB,YACpB,gBAAiB,YACjB,WAAY,YACZ,WAAY,KAAK,qBAAqB,OAAO,UAC7C,iBAAkB,eAClB,OAAQ,IAAI,MAAM,KAClB,sBAAuB,KACvB,mBAAoB,KACpB,cAAe,KACf,QAAS,GACT,OAAQ,QACR,QAAS,KAEX,+BACE,MAAO,KACP,KAAM,KACN,iBAAkB,qBAEpB,gCACE,iBAAkB,qBAEpB,gCACE,iBAAkB,qBAEpB,gCACE,SAAU,SACV,IAAK,KACL,MAAO,KACP,MAAO,KACP,OAAQ,KACR,WAAY,sBAAsB,OAAO,UACzC,QAAS,GACT,OAAQ,QACR,QAAS,KAEX,iCACE,iBAAkB,sBAEpB,wBACE,SAAU,SACV,IAAK,KACL,KAAM,KACN,OAAQ,EAAE,KAAK,EAAE,EACjB,UAAW,KACX,YAAa,KACb,MAAO,KACP,YAAa,EAAE,EAAE,IAAI,KACrB,QAAS,GACT,QAAS,KAEX,qCACE,SAAU,SACV,MAAO,KACP,OAAQ,KACR,MAAO,KACP,OAAQ,KACR,WAAY,2BAA2B,EAAE,EAAE,UAC3C,OAAQ,QACR,QAAS,GACT,QAAS,KAEX,sCACE,iBAAkB,2BAEpB,qCACE,oBAAqB,MAAM,EAI7B,iCADA,gCAGA,sCAJA,gCAGA,iCAEE,QAAS,MAET,kBAAmB,cACnB,eAAgB,cAChB,cAAe,cACf,aAAc,cACd,UAAW,cAGb,4BAEA,6BADA,8BAEA,oCAJA,8BAKE,QAAS,KAKX,wBADA,uBAEA,6BAHA,uBADA,+CAKE,oBAAqB,KACrB,mBAAoB,KACpB,iBAAkB,KAClB,gBAAiB,KACjB,YAAa,KAIf,8BADA,6BAGA,mCAJA,6BAGA,8BAEE,MAAO,KACP,QAAS,EAIX,uCACE,WAAY,MAEd,sDACE,SAAU,SAEZ,0DACE,SAAU,SAGZ,+BACE,uDACA,2DACE,MAAO,KACP,OAAQ,KACR,WAAY,SAIhB,oCACE,0BACE,WAAY,MC1OhB,4BACE,SAAU,SACV,IAAK,KACL,MAAO,KACP,OAAQ,KACR,KAAM,KACN,OAAQ,EAAE,KACV,QAAS,EACT,WAAY,KACZ,WAAY,OACZ,YAAa,KACb,QAAS,KACT,oBAAqB,KACrB,mBAAoB,KACpB,iBAAkB,KAClB,gBAAiB,KACjB,YAAa,KAEf,+BACE,QAAS,aACT,SAAU,SACV,MAAO,IACP,OAAQ,IACR,OAAQ,IAAI,IAAI,EAAE,IAClB,mBAAoB,YACpB,gBAAiB,YACjB,WAAY,YACZ,OAAQ,IAAI,MAAM,YAClB,WAAY,KACZ,WAAY,sBAA0B,OAAO,UAC7C,cAAe,IACf,WAAY,EAAE,EAAE,IAAI,KACpB,QAAS,GACT,OAAQ,QAIV,sCACE,QAAS,OAIX,oCADA,qCAEE,iBAAkB,KAClB,aAAc,KACd,QAAS,EAGX,qCACE,QAAS,EACT,QAAS,MACT,SAAU,SACV,QAAS,GACT,IAAK,KACL,KAAM,IACN,MAAO,KACP,OAAQ,KACR,WAAY,UAAU,IAAM,QAAQ,CAAE,QAAQ,IAAM,SACpD,UAAW,iBAAiB,cAAc,cAC1C,eAAgB,KAGlB,2CACE,QAAS,EACT,cAAe,IACf,WAAY,QACZ,UAAW,iBAAiB,iBAAiB,cAG/C,0CACE,QAAS,KAGX,qCACE,QAAS,MAET,kBAAmB,cACnB,eAAgB,cAChB,cAAe,cACf,aAAc,cACd,UAAW,cAEb,mCACE,QAAS,KCjFX,4DADA,sDADA,qDAGE,SAAU,SACV,IAAK,EACL,KAAM,EACN,MAAO,KACP,OAAQ,KACR,OAAQ,KAEV,4DACE,WAAY,OAAO,UACnB,gBAAiB,QAEnB,2DACE,iBAAkB,KAClB,iBAAkB,eAEpB,2DACE,SAAU,SACV,IAAK,IACL,MAAO,EACP,KAAM,EACN,OAAQ,MAAM,KAAK,EACnB,MAAO,MACP,OAAQ,MACR,WAAY,2BAA2B,OAAO,UAC9C,QAAS,GACT,OAAQ,QAEV,oEACE,iBAAkB,2BAGpB,4DADA,2DAEE,QAAS,KAEX,2DACE,WAAY,wBAAwB,OAAO,UAC3C,gBAAiB,KAAK,KAExB,gEACE,iBAAkB,wBAIpB,sDACE,OAAQ,KAEV,kEACE,KAAM,IACN,YAAa,MAGf,iEACE,QAAS"}
{"version":3,"sources":["blueimp-gallery.css","blueimp-gallery-indicator.css","blueimp-gallery-video.css"],"names":[],"mappings":"iBAYA,iBACA,+CACA,mDACE,SAAU,SACV,IAAK,EACL,MAAO,EACP,OAAQ,EACR,KAAM,EACN,mBAAoB,QAAQ,IAAK,OACjC,gBAAiB,QAAQ,IAAK,OAC9B,eAAgB,QAAQ,IAAK,OAC7B,cAAe,QAAQ,IAAK,OAC5B,WAAY,QAAQ,IAAK,OAEzB,oBAAqB,OACrB,yBAA0B,OAE5B,+CACA,mDACE,OAAQ,KACR,MAAO,KACP,OAAQ,KACR,UAAW,KACX,WAAY,KACZ,QAAS,EAEX,iBACE,SAAU,MACV,QAAS,OACT,SAAU,OACV,WAAY,KACZ,QAAS,EACT,QAAS,KACT,UAAW,IACX,iBAAkB,WAClB,aAAc,WAEhB,0BACE,SAAU,SACV,QAAS,KACT,OAAQ,IAAI,KAEZ,eAAgB,OAChB,WAAY,EAAE,EAAE,IAAI,eACpB,iBAAkB,MAAM,WACxB,aAAc,MAAM,WACpB,QAAS,MAEX,yBACE,QAAS,MACT,QAAS,EAEX,yBACE,SAAU,SACV,OAAQ,KACR,SAAU,OAEZ,kCACE,SAAU,SAEZ,gCACE,WAAY,OACZ,SAAU,SACV,MAAO,KACP,OAAQ,KACR,WAAY,OACZ,mCAAoC,kCACpC,gCAAiC,kCACjC,+BAAgC,kCAChC,8BAA+B,kCAC/B,2BAA4B,kCAG9B,uCACA,qCAFA,qCAGE,WAAY,QAEd,wCACE,WAAY,wBAAwB,OAAO,UAC3C,gBAAiB,KAAK,KAExB,6CACE,iBAAkB,wBAEpB,uDACE,QAAS,EAEX,sCACE,WAAY,sBAAsB,OAAO,UAE3C,+CACE,iBAAkB,sBAEpB,qDACE,QAAS,KAGX,+BADA,+BAEE,SAAU,SACV,IAAK,IACL,KAAM,KACN,MAAO,IACP,OAAQ,KACR,QAAS,KAAK,KAAK,KAAK,KACxB,WAAY,MACZ,mBAAoB,YACpB,gBAAiB,YACjB,WAAY,YACZ,WAAY,KAAK,qBAAqB,OAAO,UAC7C,iBAAkB,eAClB,OAAQ,IAAI,MAAM,KAClB,sBAAuB,KACvB,mBAAoB,KACpB,cAAe,KACf,QAAS,GACT,OAAQ,QACR,QAAS,KAEX,+BACE,MAAO,KACP,KAAM,KACN,iBAAkB,qBAEpB,gCACE,iBAAkB,qBAEpB,gCACE,iBAAkB,qBAEpB,gCACE,SAAU,SACV,IAAK,KACL,MAAO,KACP,MAAO,KACP,OAAQ,KACR,WAAY,sBAAsB,OAAO,UACzC,QAAS,GACT,OAAQ,QACR,QAAS,KAEX,iCACE,iBAAkB,sBAEpB,wBACE,SAAU,SACV,IAAK,KACL,KAAM,KACN,OAAQ,EAAE,KAAK,EAAE,EACjB,UAAW,KACX,YAAa,KACb,MAAO,KACP,YAAa,EAAE,EAAE,IAAI,KACrB,QAAS,GACT,QAAS,KAEX,qCACE,SAAU,SACV,MAAO,KACP,OAAQ,KACR,MAAO,KACP,OAAQ,KACR,WAAY,2BAA2B,EAAE,EAAE,UAC3C,OAAQ,QACR,QAAS,GACT,QAAS,KAEX,sCACE,iBAAkB,2BAEpB,qCACE,oBAAqB,MAAM,EAI7B,iCADA,gCAGA,sCAJA,gCAGA,iCAEE,QAAS,MAET,kBAAmB,cACnB,eAAgB,cAChB,cAAe,cACf,aAAc,cACd,UAAW,cAGb,4BAEA,6BADA,8BAEA,oCAJA,8BAKE,QAAS,KAKX,wBADA,uBAEA,6BAHA,uBADA,+CAKE,oBAAqB,KACrB,mBAAoB,KACpB,iBAAkB,KAClB,gBAAiB,KACjB,YAAa,KAIf,8BADA,6BAGA,mCAJA,6BAGA,8BAEE,MAAO,KACP,QAAS,EAIX,uCACE,WAAY,MAEd,sDACE,SAAU,SAEZ,0DACE,SAAU,SAGZ,+BACE,uDACA,2DACE,MAAO,KACP,OAAQ,KACR,WAAY,SAIhB,oCACE,0BACE,WAAY,MC1OhB,4BACE,SAAU,SACV,IAAK,KACL,MAAO,KACP,OAAQ,KACR,KAAM,KACN,OAAQ,EAAE,KACV,QAAS,EACT,WAAY,KACZ,WAAY,OACZ,YAAa,KACb,QAAS,KACT,oBAAqB,KACrB,mBAAoB,KACpB,iBAAkB,KAClB,gBAAiB,KACjB,YAAa,KAEf,+BACE,QAAS,aACT,SAAU,SACV,MAAO,IACP,OAAQ,IACR,OAAQ,IAAI,IAAI,EAAE,IAClB,mBAAoB,YACpB,gBAAiB,YACjB,WAAY,YACZ,OAAQ,IAAI,MAAM,YAClB,WAAY,KACZ,WAAY,sBAA0B,OAAO,UAC7C,cAAe,IACf,WAAY,EAAE,EAAE,IAAI,KACpB,QAAS,GACT,OAAQ,QAIV,sCACE,QAAS,OAIX,oCADA,qCAEE,iBAAkB,KAClB,aAAc,KACd,QAAS,EAGX,qCACE,QAAS,EACT,QAAS,MACT,SAAU,SACV,QAAS,GACT,IAAK,KACL,KAAM,IACN,MAAO,KACP,OAAQ,KACR,WAAY,UAAU,IAAM,QAAQ,CAAE,QAAQ,IAAM,SACpD,UAAW,iBAAiB,cAAc,cAC1C,eAAgB,KAGlB,2CACE,QAAS,EACT,cAAe,IACf,WAAY,QACZ,UAAW,iBAAiB,iBAAiB,cAG/C,0CACE,QAAS,KAGX,qCACE,QAAS,MAET,kBAAmB,cACnB,eAAgB,cAChB,cAAe,cACf,aAAc,cACd,UAAW,cAEb,mCACE,QAAS,KCjFX,4DADA,sDADA,qDAGE,SAAU,SACV,IAAK,EACL,KAAM,EACN,MAAO,KACP,OAAQ,KACR,OAAQ,KAEV,4DACE,WAAY,OAAO,UACnB,gBAAiB,QAEnB,2DACE,iBAAkB,KAClB,iBAAkB,eAEpB,2DACE,SAAU,SACV,IAAK,IACL,MAAO,EACP,KAAM,EACN,OAAQ,MAAM,KAAK,EACnB,MAAO,MACP,OAAQ,MACR,WAAY,2BAA2B,OAAO,UAC9C,QAAS,GACT,OAAQ,QAEV,oEACE,iBAAkB,2BAGpB,4DADA,2DAEE,QAAS,KAEX,2DACE,WAAY,wBAAwB,OAAO,UAC3C,gBAAiB,KAAK,KAExB,gEACE,iBAAkB,wBAIpB,sDACE,OAAQ,KAEV,kEACE,KAAM,IACN,YAAa,MAGf,iEACE,QAAS"}

View File

@@ -1,78 +1,78 @@
/*
* blueimp Gallery Demo CSS
* https://github.com/blueimp/Gallery
*
* Copyright 2013, Sebastian Tschan
* https://blueimp.net
*
* Licensed under the MIT license:
* https://opensource.org/licenses/MIT
*/
body {
max-width: 990px;
margin: 0 auto;
padding: 1em;
font-family: system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue',
Arial, sans-serif;
-webkit-text-size-adjust: 100%;
line-height: 1.4;
background: #212121;
color: #dedede;
}
a {
color: #61afef;
text-decoration: none;
}
a:visited {
color: #56b6c2;
}
a:hover {
color: #98c379;
}
img {
max-width: 100%;
border: 0;
vertical-align: middle;
}
h1,
h2,
h3,
h4,
h5,
h6 {
margin-top: 1.5em;
margin-bottom: 0.5em;
}
h1 {
margin-top: 0.5em;
}
@media (prefers-color-scheme: light) {
body {
background: #ececec;
color: #212121;
}
a {
color: #225c8d;
}
a:visited {
color: #378f9a;
}
a:hover {
color: #6fa349;
}
}
@media (min-width: 540px) {
#navigation {
list-style: none;
padding: 0;
}
#navigation li {
display: inline-block;
}
#navigation li:not(:first-child)::before {
content: ' | ';
}
}
/*
* blueimp Gallery Demo CSS
* https://github.com/blueimp/Gallery
*
* Copyright 2013, Sebastian Tschan
* https://blueimp.net
*
* Licensed under the MIT license:
* https://opensource.org/licenses/MIT
*/
body {
max-width: 990px;
margin: 0 auto;
padding: 1em;
font-family: system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue',
Arial, sans-serif;
-webkit-text-size-adjust: 100%;
line-height: 1.4;
background: #212121;
color: #dedede;
}
a {
color: #61afef;
text-decoration: none;
}
a:visited {
color: #56b6c2;
}
a:hover {
color: #98c379;
}
img {
max-width: 100%;
border: 0;
vertical-align: middle;
}
h1,
h2,
h3,
h4,
h5,
h6 {
margin-top: 1.5em;
margin-bottom: 0.5em;
}
h1 {
margin-top: 0.5em;
}
@media (prefers-color-scheme: light) {
body {
background: #ececec;
color: #212121;
}
a {
color: #225c8d;
}
a:visited {
color: #378f9a;
}
a:hover {
color: #6fa349;
}
}
@media (min-width: 540px) {
#navigation {
list-style: none;
padding: 0;
}
#navigation li {
display: inline-block;
}
#navigation li:not(:first-child)::before {
content: ' | ';
}
}

View File

Before

Width:  |  Height:  |  Size: 163 B

After

Width:  |  Height:  |  Size: 163 B

View File

@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="20" height="20">
<path d="M1 5 L5 1 L10 6 L15 1 L19 5 L14 10 L19 15 L15 19 L10 14 L5 19 L1 15 L6 10 Z" stroke="#fff" fill="#000" fill-opacity="0.5"/>
</svg>
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="20" height="20">
<path d="M1 5 L5 1 L10 6 L15 1 L19 5 L14 10 L19 15 L15 19 L10 14 L5 19 L1 15 L6 10 Z" stroke="#fff" fill="#000" fill-opacity="0.5"/>
</svg>

Before

Width:  |  Height:  |  Size: 258 B

After

Width:  |  Height:  |  Size: 262 B

View File

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="64" height="64">
<circle cx="32" cy="32" r="25" stroke="red" stroke-width="7" fill="#fff" fill-opacity="0.2"/>
<rect x="28" y="17" width="8" height="30" fill="red" transform="rotate(45, 32, 32)"/>
<rect x="28" y="17" width="8" height="30" fill="red" transform="rotate(135, 32, 32)"/>
</svg>
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="64" height="64">
<circle cx="32" cy="32" r="25" stroke="red" stroke-width="7" fill="#fff" fill-opacity="0.2"/>
<rect x="28" y="17" width="8" height="30" fill="red" transform="rotate(45, 32, 32)"/>
<rect x="28" y="17" width="8" height="30" fill="red" transform="rotate(135, 32, 32)"/>
</svg>

Before

Width:  |  Height:  |  Size: 394 B

After

Width:  |  Height:  |  Size: 400 B

View File

Before

Width:  |  Height:  |  Size: 3.7 KiB

After

Width:  |  Height:  |  Size: 3.7 KiB

View File

@@ -1,52 +1,52 @@
<?xml version="1.0" encoding="utf-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="margin: auto; background: none; display: block; shape-rendering: auto;" width="64px" height="64px" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid">
<g transform="rotate(0 50 50)">
<rect x="47" y="2" rx="3" ry="3.6" width="6" height="24" fill="#bdbdbd">
<animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="0.625s" begin="-0.5729166666666666s" repeatCount="indefinite"></animate>
</rect>
</g><g transform="rotate(30 50 50)">
<rect x="47" y="2" rx="3" ry="3.6" width="6" height="24" fill="#bdbdbd">
<animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="0.625s" begin="-0.5208333333333333s" repeatCount="indefinite"></animate>
</rect>
</g><g transform="rotate(60 50 50)">
<rect x="47" y="2" rx="3" ry="3.6" width="6" height="24" fill="#bdbdbd">
<animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="0.625s" begin="-0.46874999999999994s" repeatCount="indefinite"></animate>
</rect>
</g><g transform="rotate(90 50 50)">
<rect x="47" y="2" rx="3" ry="3.6" width="6" height="24" fill="#bdbdbd">
<animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="0.625s" begin="-0.41666666666666663s" repeatCount="indefinite"></animate>
</rect>
</g><g transform="rotate(120 50 50)">
<rect x="47" y="2" rx="3" ry="3.6" width="6" height="24" fill="#bdbdbd">
<animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="0.625s" begin="-0.36458333333333326s" repeatCount="indefinite"></animate>
</rect>
</g><g transform="rotate(150 50 50)">
<rect x="47" y="2" rx="3" ry="3.6" width="6" height="24" fill="#bdbdbd">
<animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="0.625s" begin="-0.31249999999999994s" repeatCount="indefinite"></animate>
</rect>
</g><g transform="rotate(180 50 50)">
<rect x="47" y="2" rx="3" ry="3.6" width="6" height="24" fill="#bdbdbd">
<animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="0.625s" begin="-0.26041666666666663s" repeatCount="indefinite"></animate>
</rect>
</g><g transform="rotate(210 50 50)">
<rect x="47" y="2" rx="3" ry="3.6" width="6" height="24" fill="#bdbdbd">
<animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="0.625s" begin="-0.20833333333333331s" repeatCount="indefinite"></animate>
</rect>
</g><g transform="rotate(240 50 50)">
<rect x="47" y="2" rx="3" ry="3.6" width="6" height="24" fill="#bdbdbd">
<animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="0.625s" begin="-0.15624999999999997s" repeatCount="indefinite"></animate>
</rect>
</g><g transform="rotate(270 50 50)">
<rect x="47" y="2" rx="3" ry="3.6" width="6" height="24" fill="#bdbdbd">
<animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="0.625s" begin="-0.10416666666666666s" repeatCount="indefinite"></animate>
</rect>
</g><g transform="rotate(300 50 50)">
<rect x="47" y="2" rx="3" ry="3.6" width="6" height="24" fill="#bdbdbd">
<animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="0.625s" begin="-0.05208333333333333s" repeatCount="indefinite"></animate>
</rect>
</g><g transform="rotate(330 50 50)">
<rect x="47" y="2" rx="3" ry="3.6" width="6" height="24" fill="#bdbdbd">
<animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="0.625s" begin="0s" repeatCount="indefinite"></animate>
</rect>
</g>
<?xml version="1.0" encoding="utf-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="margin: auto; background: none; display: block; shape-rendering: auto;" width="64px" height="64px" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid">
<g transform="rotate(0 50 50)">
<rect x="47" y="2" rx="3" ry="3.6" width="6" height="24" fill="#bdbdbd">
<animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="0.625s" begin="-0.5729166666666666s" repeatCount="indefinite"></animate>
</rect>
</g><g transform="rotate(30 50 50)">
<rect x="47" y="2" rx="3" ry="3.6" width="6" height="24" fill="#bdbdbd">
<animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="0.625s" begin="-0.5208333333333333s" repeatCount="indefinite"></animate>
</rect>
</g><g transform="rotate(60 50 50)">
<rect x="47" y="2" rx="3" ry="3.6" width="6" height="24" fill="#bdbdbd">
<animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="0.625s" begin="-0.46874999999999994s" repeatCount="indefinite"></animate>
</rect>
</g><g transform="rotate(90 50 50)">
<rect x="47" y="2" rx="3" ry="3.6" width="6" height="24" fill="#bdbdbd">
<animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="0.625s" begin="-0.41666666666666663s" repeatCount="indefinite"></animate>
</rect>
</g><g transform="rotate(120 50 50)">
<rect x="47" y="2" rx="3" ry="3.6" width="6" height="24" fill="#bdbdbd">
<animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="0.625s" begin="-0.36458333333333326s" repeatCount="indefinite"></animate>
</rect>
</g><g transform="rotate(150 50 50)">
<rect x="47" y="2" rx="3" ry="3.6" width="6" height="24" fill="#bdbdbd">
<animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="0.625s" begin="-0.31249999999999994s" repeatCount="indefinite"></animate>
</rect>
</g><g transform="rotate(180 50 50)">
<rect x="47" y="2" rx="3" ry="3.6" width="6" height="24" fill="#bdbdbd">
<animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="0.625s" begin="-0.26041666666666663s" repeatCount="indefinite"></animate>
</rect>
</g><g transform="rotate(210 50 50)">
<rect x="47" y="2" rx="3" ry="3.6" width="6" height="24" fill="#bdbdbd">
<animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="0.625s" begin="-0.20833333333333331s" repeatCount="indefinite"></animate>
</rect>
</g><g transform="rotate(240 50 50)">
<rect x="47" y="2" rx="3" ry="3.6" width="6" height="24" fill="#bdbdbd">
<animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="0.625s" begin="-0.15624999999999997s" repeatCount="indefinite"></animate>
</rect>
</g><g transform="rotate(270 50 50)">
<rect x="47" y="2" rx="3" ry="3.6" width="6" height="24" fill="#bdbdbd">
<animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="0.625s" begin="-0.10416666666666666s" repeatCount="indefinite"></animate>
</rect>
</g><g transform="rotate(300 50 50)">
<rect x="47" y="2" rx="3" ry="3.6" width="6" height="24" fill="#bdbdbd">
<animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="0.625s" begin="-0.05208333333333333s" repeatCount="indefinite"></animate>
</rect>
</g><g transform="rotate(330 50 50)">
<rect x="47" y="2" rx="3" ry="3.6" width="6" height="24" fill="#bdbdbd">
<animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="0.625s" begin="0s" repeatCount="indefinite"></animate>
</rect>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

View File

Before

Width:  |  Height:  |  Size: 166 B

After

Width:  |  Height:  |  Size: 166 B

View File

@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="8" height="20">
<path d="M0 0 V2 L6 10 L0 18 V20 L8 10 Z" stroke="#fff" fill="#fff"/>
</svg>
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="8" height="20">
<path d="M0 0 V2 L6 10 L0 18 V20 L8 10 Z" stroke="#fff" fill="#fff"/>
</svg>

Before

Width:  |  Height:  |  Size: 194 B

After

Width:  |  Height:  |  Size: 198 B

View File

Before

Width:  |  Height:  |  Size: 432 B

After

Width:  |  Height:  |  Size: 432 B

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="60" height="30">
<polygon points="5,2 5,28 27,15" stroke="#fff" stroke-width="2" fill="#000" fill-opacity="0.5"/>
<rect x="35" y="3" width="8" height="24" stroke="#fff" stroke-width="2" fill="#000" fill-opacity="0.5"/>
<rect x="47" y="3" width="8" height="24" stroke="#fff" stroke-width="2" fill="#000" fill-opacity="0.5"/>
</svg>
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="60" height="30">
<polygon points="5,2 5,28 27,15" stroke="#fff" stroke-width="2" fill="#000" fill-opacity="0.5"/>
<rect x="35" y="3" width="8" height="24" stroke="#fff" stroke-width="2" fill="#000" fill-opacity="0.5"/>
<rect x="47" y="3" width="8" height="24" stroke="#fff" stroke-width="2" fill="#000" fill-opacity="0.5"/>
</svg>

Before

Width:  |  Height:  |  Size: 434 B

After

Width:  |  Height:  |  Size: 440 B

View File

Before

Width:  |  Height:  |  Size: 170 B

After

Width:  |  Height:  |  Size: 170 B

View File

@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="8" height="20">
<path d="M8 0 V2 L2 10 L8 18 V20 L0 10 Z" stroke="#fff" fill="#fff"/>
</svg>
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="8" height="20">
<path d="M8 0 V2 L2 10 L8 18 V20 L0 10 Z" stroke="#fff" fill="#fff"/>
</svg>

Before

Width:  |  Height:  |  Size: 194 B

After

Width:  |  Height:  |  Size: 198 B

View File

Before

Width:  |  Height:  |  Size: 993 B

After

Width:  |  Height:  |  Size: 993 B

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="64" height="64">
<circle cx="32" cy="32" r="25" stroke="#fff" stroke-width="7" fill="#000" fill-opacity="0.2"/>
<polygon points="26,22 26,42 43,32" fill="#fff"/>
</svg>
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="64" height="64">
<circle cx="32" cy="32" r="25" stroke="#fff" stroke-width="7" fill="#000" fill-opacity="0.2"/>
<polygon points="26,22 26,42 43,32" fill="#fff"/>
</svg>

Before

Width:  |  Height:  |  Size: 271 B

After

Width:  |  Height:  |  Size: 276 B

View File

@@ -1,158 +1,158 @@
<!DOCTYPE html>
<!--
/*
* blueimp Gallery Demo
* https://github.com/blueimp/Gallery
*
* Copyright 2013, Sebastian Tschan
* https://blueimp.net
*
* Licensed under the MIT license:
* https://opensource.org/licenses/MIT
*/
-->
<html lang="en">
<head>
<!--[if IE]>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<![endif]-->
<meta charset="utf-8" />
<title>blueimp Gallery</title>
<meta
name="description"
content="blueimp Gallery is a touch-enabled, responsive and customizable image and video gallery, carousel and lightbox, optimized for both mobile and desktop web browsers. It features swipe, mouse and keyboard navigation, transition effects, slideshow functionality, fullscreen support and on-demand content loading and can be extended to display additional content types."
/>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="css/blueimp-gallery.css" />
<link rel="stylesheet" href="css/blueimp-gallery-indicator.css" />
<link rel="stylesheet" href="css/blueimp-gallery-video.css" />
<link rel="stylesheet" href="css/demo/demo.css" />
</head>
<body>
<h1>blueimp Gallery</h1>
<p>
<a href="https://github.com/blueimp/Gallery">blueimp Gallery</a> is a
touch-enabled, responsive and customizable image &amp; video gallery,
carousel and lightbox, optimized for both mobile and desktop web browsers.
</p>
<p>
It features swipe, mouse and keyboard navigation, transition effects,
slideshow functionality, fullscreen support and on-demand content loading
and can be extended to display additional content types.
</p>
<ul id="navigation">
<li>
<a href="https://github.com/blueimp/Gallery/releases">Download</a>
</li>
<li><a href="https://github.com/blueimp/Gallery">Source Code</a></li>
<li>
<a href="https://github.com/blueimp/Gallery/blob/master/README.md"
>Documentation</a
>
</li>
<li><a href="https://blueimp.net">&copy; Sebastian Tschan</a></li>
</ul>
<h2>Carousel image gallery</h2>
<!-- The Gallery as inline carousel -->
<div
id="blueimp-image-carousel"
class="blueimp-gallery blueimp-gallery-carousel"
aria-label="image carousel"
>
<div class="slides" aria-live="off"></div>
<h3 class="title"></h3>
<a
class="prev"
aria-controls="blueimp-image-carousel"
aria-label="previous slide"
></a>
<a
class="next"
aria-controls="blueimp-image-carousel"
aria-label="next slide"
></a>
<a
class="play-pause"
aria-controls="blueimp-image-carousel"
aria-label="play slideshow"
aria-pressed="true"
role="button"
></a>
</div>
<h2>Carousel video gallery</h2>
<!-- The Gallery as inline carousel -->
<div
id="blueimp-video-carousel"
class="blueimp-gallery blueimp-gallery-controls blueimp-gallery-carousel"
aria-label="video carousel"
>
<div class="slides" aria-live="polite"></div>
<h3 class="title"></h3>
<a
class="prev"
aria-controls="blueimp-video-carousel"
aria-label="previous slide"
></a>
<a
class="next"
aria-controls="blueimp-video-carousel"
aria-label="next slide"
></a>
</div>
<h2>Lightbox image gallery</h2>
<p>
<input type="checkbox" id="fullscreen" />
<label for="fullscreen">Fullscreen</label>
</p>
<!-- The container for the list of example images -->
<div id="links" class="links"></div>
<!-- The Gallery as lightbox dialog -->
<div
id="blueimp-gallery"
class="blueimp-gallery"
aria-label="image gallery"
aria-modal="true"
role="dialog"
>
<div class="slides" aria-live="polite"></div>
<h3 class="title"></h3>
<a
class="prev"
aria-controls="blueimp-gallery"
aria-label="previous slide"
aria-keyshortcuts="ArrowLeft"
></a>
<a
class="next"
aria-controls="blueimp-gallery"
aria-label="next slide"
aria-keyshortcuts="ArrowRight"
></a>
<a
class="close"
aria-controls="blueimp-gallery"
aria-label="close"
aria-keyshortcuts="Escape"
></a>
<a
class="play-pause"
aria-controls="blueimp-gallery"
aria-label="play slideshow"
aria-keyshortcuts="Space"
aria-pressed="false"
role="button"
></a>
<ol class="indicator"></ol>
</div>
<script src="js/blueimp-helper.js"></script>
<script src="js/blueimp-gallery.js"></script>
<script src="js/blueimp-gallery-fullscreen.js"></script>
<script src="js/blueimp-gallery-indicator.js"></script>
<script src="js/blueimp-gallery-video.js"></script>
<script src="js/blueimp-gallery-vimeo.js"></script>
<script src="js/blueimp-gallery-youtube.js"></script>
<script src="js/vendor/jquery.js"></script>
<script src="js/jquery.blueimp-gallery.js"></script>
<script src="js/demo/demo.js"></script>
</body>
</html>
<!DOCTYPE html>
<!--
/*
* blueimp Gallery Demo
* https://github.com/blueimp/Gallery
*
* Copyright 2013, Sebastian Tschan
* https://blueimp.net
*
* Licensed under the MIT license:
* https://opensource.org/licenses/MIT
*/
-->
<html lang="en">
<head>
<!--[if IE]>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<![endif]-->
<meta charset="utf-8" />
<title>blueimp Gallery</title>
<meta
name="description"
content="blueimp Gallery is a touch-enabled, responsive and customizable image and video gallery, carousel and lightbox, optimized for both mobile and desktop web browsers. It features swipe, mouse and keyboard navigation, transition effects, slideshow functionality, fullscreen support and on-demand content loading and can be extended to display additional content types."
/>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="css/blueimp-gallery.css" />
<link rel="stylesheet" href="css/blueimp-gallery-indicator.css" />
<link rel="stylesheet" href="css/blueimp-gallery-video.css" />
<link rel="stylesheet" href="css/demo/demo.css" />
</head>
<body>
<h1>blueimp Gallery</h1>
<p>
<a href="https://github.com/blueimp/Gallery">blueimp Gallery</a> is a
touch-enabled, responsive and customizable image &amp; video gallery,
carousel and lightbox, optimized for both mobile and desktop web browsers.
</p>
<p>
It features swipe, mouse and keyboard navigation, transition effects,
slideshow functionality, fullscreen support and on-demand content loading
and can be extended to display additional content types.
</p>
<ul id="navigation">
<li>
<a href="https://github.com/blueimp/Gallery/releases">Download</a>
</li>
<li><a href="https://github.com/blueimp/Gallery">Source Code</a></li>
<li>
<a href="https://github.com/blueimp/Gallery/blob/master/README.md"
>Documentation</a
>
</li>
<li><a href="https://blueimp.net">&copy; Sebastian Tschan</a></li>
</ul>
<h2>Carousel image gallery</h2>
<!-- The Gallery as inline carousel -->
<div
id="blueimp-image-carousel"
class="blueimp-gallery blueimp-gallery-carousel"
aria-label="image carousel"
>
<div class="slides" aria-live="off"></div>
<h3 class="title"></h3>
<a
class="prev"
aria-controls="blueimp-image-carousel"
aria-label="previous slide"
></a>
<a
class="next"
aria-controls="blueimp-image-carousel"
aria-label="next slide"
></a>
<a
class="play-pause"
aria-controls="blueimp-image-carousel"
aria-label="play slideshow"
aria-pressed="true"
role="button"
></a>
</div>
<h2>Carousel video gallery</h2>
<!-- The Gallery as inline carousel -->
<div
id="blueimp-video-carousel"
class="blueimp-gallery blueimp-gallery-controls blueimp-gallery-carousel"
aria-label="video carousel"
>
<div class="slides" aria-live="polite"></div>
<h3 class="title"></h3>
<a
class="prev"
aria-controls="blueimp-video-carousel"
aria-label="previous slide"
></a>
<a
class="next"
aria-controls="blueimp-video-carousel"
aria-label="next slide"
></a>
</div>
<h2>Lightbox image gallery</h2>
<p>
<input type="checkbox" id="fullscreen" />
<label for="fullscreen">Fullscreen</label>
</p>
<!-- The container for the list of example images -->
<div id="links" class="links"></div>
<!-- The Gallery as lightbox dialog -->
<div
id="blueimp-gallery"
class="blueimp-gallery"
aria-label="image gallery"
aria-modal="true"
role="dialog"
>
<div class="slides" aria-live="polite"></div>
<h3 class="title"></h3>
<a
class="prev"
aria-controls="blueimp-gallery"
aria-label="previous slide"
aria-keyshortcuts="ArrowLeft"
></a>
<a
class="next"
aria-controls="blueimp-gallery"
aria-label="next slide"
aria-keyshortcuts="ArrowRight"
></a>
<a
class="close"
aria-controls="blueimp-gallery"
aria-label="close"
aria-keyshortcuts="Escape"
></a>
<a
class="play-pause"
aria-controls="blueimp-gallery"
aria-label="play slideshow"
aria-keyshortcuts="Space"
aria-pressed="false"
role="button"
></a>
<ol class="indicator"></ol>
</div>
<script src="js/blueimp-helper.js"></script>
<script src="js/blueimp-gallery.js"></script>
<script src="js/blueimp-gallery-fullscreen.js"></script>
<script src="js/blueimp-gallery-indicator.js"></script>
<script src="js/blueimp-gallery-video.js"></script>
<script src="js/blueimp-gallery-vimeo.js"></script>
<script src="js/blueimp-gallery-youtube.js"></script>
<script src="js/vendor/jquery.js"></script>
<script src="js/jquery.blueimp-gallery.js"></script>
<script src="js/demo/demo.js"></script>
</body>
</html>

View File

@@ -1,86 +1,86 @@
/*
* blueimp Gallery Fullscreen JS
* https://github.com/blueimp/Gallery
*
* Copyright 2013, Sebastian Tschan
* https://blueimp.net
*
* Licensed under the MIT license:
* https://opensource.org/licenses/MIT
*/
/* global define */
;(function (factory) {
'use strict'
if (typeof define === 'function' && define.amd) {
// Register as an anonymous AMD module:
define(['./blueimp-helper', './blueimp-gallery'], factory)
} else {
// Browser globals:
factory(window.blueimp.helper || window.jQuery, window.blueimp.Gallery)
}
})(function ($, Gallery) {
'use strict'
var galleryPrototype = Gallery.prototype
$.extend(galleryPrototype.options, {
// Defines if the gallery should open in fullscreen mode:
fullscreen: false
})
var initialize = galleryPrototype.initialize
var close = galleryPrototype.close
$.extend(galleryPrototype, {
getFullScreenElement: function () {
return (
document.fullscreenElement ||
document.webkitFullscreenElement ||
document.mozFullScreenElement ||
document.msFullscreenElement
)
},
requestFullScreen: function (element) {
if (element.requestFullscreen) {
element.requestFullscreen()
} else if (element.webkitRequestFullscreen) {
element.webkitRequestFullscreen()
} else if (element.mozRequestFullScreen) {
element.mozRequestFullScreen()
} else if (element.msRequestFullscreen) {
element.msRequestFullscreen()
}
},
exitFullScreen: function () {
if (document.exitFullscreen) {
document.exitFullscreen()
} else if (document.webkitCancelFullScreen) {
document.webkitCancelFullScreen()
} else if (document.mozCancelFullScreen) {
document.mozCancelFullScreen()
} else if (document.msExitFullscreen) {
document.msExitFullscreen()
}
},
initialize: function () {
initialize.call(this)
if (this.options.fullscreen && !this.getFullScreenElement()) {
this.requestFullScreen(this.container[0])
}
},
close: function () {
if (this.getFullScreenElement() === this.container[0]) {
this.exitFullScreen()
}
close.call(this)
}
})
return Gallery
})
/*
* blueimp Gallery Fullscreen JS
* https://github.com/blueimp/Gallery
*
* Copyright 2013, Sebastian Tschan
* https://blueimp.net
*
* Licensed under the MIT license:
* https://opensource.org/licenses/MIT
*/
/* global define */
;(function (factory) {
'use strict'
if (typeof define === 'function' && define.amd) {
// Register as an anonymous AMD module:
define(['./blueimp-helper', './blueimp-gallery'], factory)
} else {
// Browser globals:
factory(window.blueimp.helper || window.jQuery, window.blueimp.Gallery)
}
})(function ($, Gallery) {
'use strict'
var galleryPrototype = Gallery.prototype
$.extend(galleryPrototype.options, {
// Defines if the gallery should open in fullscreen mode:
fullscreen: false
})
var initialize = galleryPrototype.initialize
var close = galleryPrototype.close
$.extend(galleryPrototype, {
getFullScreenElement: function () {
return (
document.fullscreenElement ||
document.webkitFullscreenElement ||
document.mozFullScreenElement ||
document.msFullscreenElement
)
},
requestFullScreen: function (element) {
if (element.requestFullscreen) {
element.requestFullscreen()
} else if (element.webkitRequestFullscreen) {
element.webkitRequestFullscreen()
} else if (element.mozRequestFullScreen) {
element.mozRequestFullScreen()
} else if (element.msRequestFullscreen) {
element.msRequestFullscreen()
}
},
exitFullScreen: function () {
if (document.exitFullscreen) {
document.exitFullscreen()
} else if (document.webkitCancelFullScreen) {
document.webkitCancelFullScreen()
} else if (document.mozCancelFullScreen) {
document.mozCancelFullScreen()
} else if (document.msExitFullscreen) {
document.msExitFullscreen()
}
},
initialize: function () {
initialize.call(this)
if (this.options.fullscreen && !this.getFullScreenElement()) {
this.requestFullScreen(this.container[0])
}
},
close: function () {
if (this.getFullScreenElement() === this.container[0]) {
this.exitFullScreen()
}
close.call(this)
}
})
return Gallery
})

View File

@@ -1,148 +1,148 @@
/*
* blueimp Gallery Indicator JS
* https://github.com/blueimp/Gallery
*
* Copyright 2013, Sebastian Tschan
* https://blueimp.net
*
* Licensed under the MIT license:
* https://opensource.org/licenses/MIT
*/
/* global define */
;(function (factory) {
'use strict'
if (typeof define === 'function' && define.amd) {
// Register as an anonymous AMD module:
define(['./blueimp-helper', './blueimp-gallery'], factory)
} else {
// Browser globals:
factory(window.blueimp.helper || window.jQuery, window.blueimp.Gallery)
}
})(function ($, Gallery) {
'use strict'
var galleryPrototype = Gallery.prototype
$.extend(galleryPrototype.options, {
// The tag name, Id, element or querySelector of the indicator container:
indicatorContainer: 'ol',
// The class for the active indicator:
activeIndicatorClass: 'active',
// The list object property (or data attribute) with the thumbnail URL,
// used as alternative to a thumbnail child element:
thumbnailProperty: 'thumbnail',
// Defines if the gallery indicators should display a thumbnail:
thumbnailIndicators: true
})
var initSlides = galleryPrototype.initSlides
var addSlide = galleryPrototype.addSlide
var resetSlides = galleryPrototype.resetSlides
var handleClick = galleryPrototype.handleClick
var handleSlide = galleryPrototype.handleSlide
var handleClose = galleryPrototype.handleClose
$.extend(galleryPrototype, {
createIndicator: function (obj) {
var indicator = this.indicatorPrototype.cloneNode(false)
var title = this.getItemProperty(obj, this.options.titleProperty)
var thumbnailProperty = this.options.thumbnailProperty
var thumbnailUrl
var thumbnail
if (this.options.thumbnailIndicators) {
if (thumbnailProperty) {
thumbnailUrl = this.getItemProperty(obj, thumbnailProperty)
}
if (thumbnailUrl === undefined) {
thumbnail = obj.getElementsByTagName && $(obj).find('img')[0]
if (thumbnail) {
thumbnailUrl = thumbnail.src
}
}
if (thumbnailUrl) {
indicator.style.backgroundImage = 'url("' + thumbnailUrl + '")'
}
}
if (title) {
indicator.title = title
}
indicator.setAttribute('role', 'link')
return indicator
},
addIndicator: function (index) {
if (this.indicatorContainer.length) {
var indicator = this.createIndicator(this.list[index])
indicator.setAttribute('data-index', index)
this.indicatorContainer[0].appendChild(indicator)
this.indicators.push(indicator)
}
},
setActiveIndicator: function (index) {
if (this.indicators) {
if (this.activeIndicator) {
this.activeIndicator.removeClass(this.options.activeIndicatorClass)
}
this.activeIndicator = $(this.indicators[index])
this.activeIndicator.addClass(this.options.activeIndicatorClass)
}
},
initSlides: function (reload) {
if (!reload) {
this.indicatorContainer = this.container.find(
this.options.indicatorContainer
)
if (this.indicatorContainer.length) {
this.indicatorPrototype = document.createElement('li')
this.indicators = this.indicatorContainer[0].children
}
}
initSlides.call(this, reload)
},
addSlide: function (index) {
addSlide.call(this, index)
this.addIndicator(index)
},
resetSlides: function () {
resetSlides.call(this)
this.indicatorContainer.empty()
this.indicators = []
},
handleClick: function (event) {
var target = event.target || event.srcElement
var parent = target.parentNode
if (parent === this.indicatorContainer[0]) {
// Click on indicator element
this.preventDefault(event)
this.slide(this.getNodeIndex(target))
} else if (parent.parentNode === this.indicatorContainer[0]) {
// Click on indicator child element
this.preventDefault(event)
this.slide(this.getNodeIndex(parent))
} else {
return handleClick.call(this, event)
}
},
handleSlide: function (oldIndex, newIndex) {
handleSlide.call(this, oldIndex, newIndex)
this.setActiveIndicator(newIndex)
},
handleClose: function () {
if (this.activeIndicator) {
this.activeIndicator.removeClass(this.options.activeIndicatorClass)
}
handleClose.call(this)
}
})
return Gallery
})
/*
* blueimp Gallery Indicator JS
* https://github.com/blueimp/Gallery
*
* Copyright 2013, Sebastian Tschan
* https://blueimp.net
*
* Licensed under the MIT license:
* https://opensource.org/licenses/MIT
*/
/* global define */
;(function (factory) {
'use strict'
if (typeof define === 'function' && define.amd) {
// Register as an anonymous AMD module:
define(['./blueimp-helper', './blueimp-gallery'], factory)
} else {
// Browser globals:
factory(window.blueimp.helper || window.jQuery, window.blueimp.Gallery)
}
})(function ($, Gallery) {
'use strict'
var galleryPrototype = Gallery.prototype
$.extend(galleryPrototype.options, {
// The tag name, Id, element or querySelector of the indicator container:
indicatorContainer: 'ol',
// The class for the active indicator:
activeIndicatorClass: 'active',
// The list object property (or data attribute) with the thumbnail URL,
// used as alternative to a thumbnail child element:
thumbnailProperty: 'thumbnail',
// Defines if the gallery indicators should display a thumbnail:
thumbnailIndicators: true
})
var initSlides = galleryPrototype.initSlides
var addSlide = galleryPrototype.addSlide
var resetSlides = galleryPrototype.resetSlides
var handleClick = galleryPrototype.handleClick
var handleSlide = galleryPrototype.handleSlide
var handleClose = galleryPrototype.handleClose
$.extend(galleryPrototype, {
createIndicator: function (obj) {
var indicator = this.indicatorPrototype.cloneNode(false)
var title = this.getItemProperty(obj, this.options.titleProperty)
var thumbnailProperty = this.options.thumbnailProperty
var thumbnailUrl
var thumbnail
if (this.options.thumbnailIndicators) {
if (thumbnailProperty) {
thumbnailUrl = this.getItemProperty(obj, thumbnailProperty)
}
if (thumbnailUrl === undefined) {
thumbnail = obj.getElementsByTagName && $(obj).find('img')[0]
if (thumbnail) {
thumbnailUrl = thumbnail.src
}
}
if (thumbnailUrl) {
indicator.style.backgroundImage = 'url("' + thumbnailUrl + '")'
}
}
if (title) {
indicator.title = title
}
indicator.setAttribute('role', 'link')
return indicator
},
addIndicator: function (index) {
if (this.indicatorContainer.length) {
var indicator = this.createIndicator(this.list[index])
indicator.setAttribute('data-index', index)
this.indicatorContainer[0].appendChild(indicator)
this.indicators.push(indicator)
}
},
setActiveIndicator: function (index) {
if (this.indicators) {
if (this.activeIndicator) {
this.activeIndicator.removeClass(this.options.activeIndicatorClass)
}
this.activeIndicator = $(this.indicators[index])
this.activeIndicator.addClass(this.options.activeIndicatorClass)
}
},
initSlides: function (reload) {
if (!reload) {
this.indicatorContainer = this.container.find(
this.options.indicatorContainer
)
if (this.indicatorContainer.length) {
this.indicatorPrototype = document.createElement('li')
this.indicators = this.indicatorContainer[0].children
}
}
initSlides.call(this, reload)
},
addSlide: function (index) {
addSlide.call(this, index)
this.addIndicator(index)
},
resetSlides: function () {
resetSlides.call(this)
this.indicatorContainer.empty()
this.indicators = []
},
handleClick: function (event) {
var target = event.target || event.srcElement
var parent = target.parentNode
if (parent === this.indicatorContainer[0]) {
// Click on indicator element
this.preventDefault(event)
this.slide(this.getNodeIndex(target))
} else if (parent.parentNode === this.indicatorContainer[0]) {
// Click on indicator child element
this.preventDefault(event)
this.slide(this.getNodeIndex(parent))
} else {
return handleClick.call(this, event)
}
},
handleSlide: function (oldIndex, newIndex) {
handleSlide.call(this, oldIndex, newIndex)
this.setActiveIndicator(newIndex)
},
handleClose: function () {
if (this.activeIndicator) {
this.activeIndicator.removeClass(this.options.activeIndicatorClass)
}
handleClose.call(this)
}
})
return Gallery
})

View File

@@ -1,188 +1,188 @@
/*
* blueimp Gallery Video Factory JS
* https://github.com/blueimp/Gallery
*
* Copyright 2013, Sebastian Tschan
* https://blueimp.net
*
* Licensed under the MIT license:
* https://opensource.org/licenses/MIT
*/
/* global define */
;(function (factory) {
'use strict'
if (typeof define === 'function' && define.amd) {
// Register as an anonymous AMD module:
define(['./blueimp-helper', './blueimp-gallery'], factory)
} else {
// Browser globals:
factory(window.blueimp.helper || window.jQuery, window.blueimp.Gallery)
}
})(function ($, Gallery) {
'use strict'
var galleryPrototype = Gallery.prototype
$.extend(galleryPrototype.options, {
// The class for video content elements:
videoContentClass: 'video-content',
// The class for video when it is loading:
videoLoadingClass: 'video-loading',
// The class for video when it is playing:
videoPlayingClass: 'video-playing',
// The class for video content displayed in an iframe:
videoIframeClass: 'video-iframe',
// The class for the video cover element:
videoCoverClass: 'video-cover',
// The class for the video play control:
videoPlayClass: 'video-play',
// Play videos inline by default:
videoPlaysInline: true,
// The list object property (or data attribute) for video preload:
videoPreloadProperty: 'preload',
// The list object property (or data attribute) for the video poster URL:
videoPosterProperty: 'poster'
})
var handleSlide = galleryPrototype.handleSlide
$.extend(galleryPrototype, {
handleSlide: function (oldIndex, newIndex) {
handleSlide.call(this, oldIndex, newIndex)
this.setTimeout(function () {
if (this.activeVideo) {
this.activeVideo.pause()
}
})
},
videoFactory: function (obj, callback, videoInterface) {
var that = this
var options = this.options
var videoContainerNode = this.elementPrototype.cloneNode(false)
var videoContainer = $(videoContainerNode)
var errorArgs = [
{
type: 'error',
target: videoContainerNode
}
]
var video = videoInterface || document.createElement('video')
var coverElement = this.elementPrototype.cloneNode(false)
var playElement = document.createElement('a')
var url = this.getItemProperty(obj, options.urlProperty)
var sources = this.getItemProperty(obj, options.sourcesProperty)
var title = this.getItemProperty(obj, options.titleProperty)
var posterUrl = this.getItemProperty(obj, options.videoPosterProperty)
var playControls = [playElement]
var hasGalleryControls
var isLoading
var i
videoContainer.addClass(options.videoContentClass)
$(playElement).addClass(options.videoPlayClass)
if (
!$(coverElement)
.addClass(options.videoCoverClass)
.hasClass(options.toggleClass)
) {
playControls.push(coverElement)
}
coverElement.draggable = false
if (title) {
videoContainerNode.title = title
playElement.setAttribute('aria-label', title)
}
if (posterUrl) {
// Set as background image instead of as poster video element property:
// - Is accessible for browsers that do not support the video element
// - Is accessible for both video element and iframe video players
// - Avoids visual artifacts in IE with the poster property set
coverElement.style.backgroundImage = 'url("' + posterUrl + '")'
}
if (video.setAttribute) {
if (options.videoPlaysInline) video.setAttribute('playsinline', '')
} else {
videoContainer.addClass(options.videoIframeClass)
}
video.preload =
this.getItemProperty(obj, options.videoPreloadProperty) || 'none'
if (this.support.source && sources) {
for (i = 0; i < sources.length; i += 1) {
video.appendChild(
$.extend(this.sourcePrototype.cloneNode(false), sources[i])
)
}
}
if (url) video.src = url
playElement.href = url || (sources && sources.length && sources[0].src)
if (video.play && video.pause) {
;(videoInterface || $(video))
.on('error', function () {
that.setTimeout(callback, errorArgs)
})
.on('pause', function () {
if (video.seeking) return
isLoading = false
videoContainer
.removeClass(that.options.videoLoadingClass)
.removeClass(that.options.videoPlayingClass)
if (hasGalleryControls) {
that.container.addClass(that.options.controlsClass)
}
video.controls = false
if (video === that.activeVideo) delete that.activeVideo
if (that.interval) {
// Continue slideshow interval
that.play()
}
})
.on('playing', function () {
isLoading = false
coverElement.removeAttribute('style')
videoContainer
.removeClass(that.options.videoLoadingClass)
.addClass(that.options.videoPlayingClass)
})
.on('play', function () {
// Clear slideshow timeout:
window.clearTimeout(that.timeout)
isLoading = true
videoContainer.addClass(that.options.videoLoadingClass)
if (that.container.hasClass(that.options.controlsClass)) {
hasGalleryControls = true
that.container.removeClass(that.options.controlsClass)
} else {
hasGalleryControls = false
}
video.controls = true
that.activeVideo = video
})
$(playControls).on('click', function (event) {
that.preventDefault(event)
that.activeVideo = video
if (isLoading) {
video.pause()
} else {
video.play()
}
})
videoContainerNode.appendChild(
(videoInterface && videoInterface.element) || video
)
}
videoContainerNode.appendChild(coverElement)
videoContainerNode.appendChild(playElement)
this.setTimeout(callback, [
{
type: 'load',
target: videoContainerNode
}
])
return videoContainerNode
}
})
return Gallery
})
/*
* blueimp Gallery Video Factory JS
* https://github.com/blueimp/Gallery
*
* Copyright 2013, Sebastian Tschan
* https://blueimp.net
*
* Licensed under the MIT license:
* https://opensource.org/licenses/MIT
*/
/* global define */
;(function (factory) {
'use strict'
if (typeof define === 'function' && define.amd) {
// Register as an anonymous AMD module:
define(['./blueimp-helper', './blueimp-gallery'], factory)
} else {
// Browser globals:
factory(window.blueimp.helper || window.jQuery, window.blueimp.Gallery)
}
})(function ($, Gallery) {
'use strict'
var galleryPrototype = Gallery.prototype
$.extend(galleryPrototype.options, {
// The class for video content elements:
videoContentClass: 'video-content',
// The class for video when it is loading:
videoLoadingClass: 'video-loading',
// The class for video when it is playing:
videoPlayingClass: 'video-playing',
// The class for video content displayed in an iframe:
videoIframeClass: 'video-iframe',
// The class for the video cover element:
videoCoverClass: 'video-cover',
// The class for the video play control:
videoPlayClass: 'video-play',
// Play videos inline by default:
videoPlaysInline: true,
// The list object property (or data attribute) for video preload:
videoPreloadProperty: 'preload',
// The list object property (or data attribute) for the video poster URL:
videoPosterProperty: 'poster'
})
var handleSlide = galleryPrototype.handleSlide
$.extend(galleryPrototype, {
handleSlide: function (oldIndex, newIndex) {
handleSlide.call(this, oldIndex, newIndex)
this.setTimeout(function () {
if (this.activeVideo) {
this.activeVideo.pause()
}
})
},
videoFactory: function (obj, callback, videoInterface) {
var that = this
var options = this.options
var videoContainerNode = this.elementPrototype.cloneNode(false)
var videoContainer = $(videoContainerNode)
var errorArgs = [
{
type: 'error',
target: videoContainerNode
}
]
var video = videoInterface || document.createElement('video')
var coverElement = this.elementPrototype.cloneNode(false)
var playElement = document.createElement('a')
var url = this.getItemProperty(obj, options.urlProperty)
var sources = this.getItemProperty(obj, options.sourcesProperty)
var title = this.getItemProperty(obj, options.titleProperty)
var posterUrl = this.getItemProperty(obj, options.videoPosterProperty)
var playControls = [playElement]
var hasGalleryControls
var isLoading
var i
videoContainer.addClass(options.videoContentClass)
$(playElement).addClass(options.videoPlayClass)
if (
!$(coverElement)
.addClass(options.videoCoverClass)
.hasClass(options.toggleClass)
) {
playControls.push(coverElement)
}
coverElement.draggable = false
if (title) {
videoContainerNode.title = title
playElement.setAttribute('aria-label', title)
}
if (posterUrl) {
// Set as background image instead of as poster video element property:
// - Is accessible for browsers that do not support the video element
// - Is accessible for both video element and iframe video players
// - Avoids visual artifacts in IE with the poster property set
coverElement.style.backgroundImage = 'url("' + posterUrl + '")'
}
if (video.setAttribute) {
if (options.videoPlaysInline) video.setAttribute('playsinline', '')
} else {
videoContainer.addClass(options.videoIframeClass)
}
video.preload =
this.getItemProperty(obj, options.videoPreloadProperty) || 'none'
if (this.support.source && sources) {
for (i = 0; i < sources.length; i += 1) {
video.appendChild(
$.extend(this.sourcePrototype.cloneNode(false), sources[i])
)
}
}
if (url) video.src = url
playElement.href = url || (sources && sources.length && sources[0].src)
if (video.play && video.pause) {
;(videoInterface || $(video))
.on('error', function () {
that.setTimeout(callback, errorArgs)
})
.on('pause', function () {
if (video.seeking) return
isLoading = false
videoContainer
.removeClass(that.options.videoLoadingClass)
.removeClass(that.options.videoPlayingClass)
if (hasGalleryControls) {
that.container.addClass(that.options.controlsClass)
}
video.controls = false
if (video === that.activeVideo) delete that.activeVideo
if (that.interval) {
// Continue slideshow interval
that.play()
}
})
.on('playing', function () {
isLoading = false
coverElement.removeAttribute('style')
videoContainer
.removeClass(that.options.videoLoadingClass)
.addClass(that.options.videoPlayingClass)
})
.on('play', function () {
// Clear slideshow timeout:
window.clearTimeout(that.timeout)
isLoading = true
videoContainer.addClass(that.options.videoLoadingClass)
if (that.container.hasClass(that.options.controlsClass)) {
hasGalleryControls = true
that.container.removeClass(that.options.controlsClass)
} else {
hasGalleryControls = false
}
video.controls = true
that.activeVideo = video
})
$(playControls).on('click', function (event) {
that.preventDefault(event)
that.activeVideo = video
if (isLoading) {
video.pause()
} else {
video.play()
}
})
videoContainerNode.appendChild(
(videoInterface && videoInterface.element) || video
)
}
videoContainerNode.appendChild(coverElement)
videoContainerNode.appendChild(playElement)
this.setTimeout(callback, [
{
type: 'load',
target: videoContainerNode
}
])
return videoContainerNode
}
})
return Gallery
})

View File

@@ -1,212 +1,212 @@
/*
* blueimp Gallery Vimeo Video Factory JS
* https://github.com/blueimp/Gallery
*
* Copyright 2013, Sebastian Tschan
* https://blueimp.net
*
* Licensed under the MIT license:
* https://opensource.org/licenses/MIT
*/
/* global define, $f */
;(function (factory) {
'use strict'
if (typeof define === 'function' && define.amd) {
// Register as an anonymous AMD module:
define(['./blueimp-helper', './blueimp-gallery-video'], factory)
} else {
// Browser globals:
factory(window.blueimp.helper || window.jQuery, window.blueimp.Gallery)
}
})(function ($, Gallery) {
'use strict'
if (!window.postMessage) {
return Gallery
}
var galleryPrototype = Gallery.prototype
$.extend(galleryPrototype.options, {
// The list object property (or data attribute) with the Vimeo video id:
vimeoVideoIdProperty: 'vimeo',
// The URL for the Vimeo video player, can be extended with custom parameters:
// https://developer.vimeo.com/player/embedding
vimeoPlayerUrl:
'https://player.vimeo.com/video/VIDEO_ID?api=1&player_id=PLAYER_ID',
// The prefix for the Vimeo video player ID:
vimeoPlayerIdPrefix: 'vimeo-player-',
// Require a click on the native Vimeo player for the initial playback:
vimeoClickToPlay: false
})
var textFactory =
galleryPrototype.textFactory || galleryPrototype.imageFactory
var VimeoPlayer = function (url, videoId, playerId, clickToPlay) {
this.url = url
this.videoId = videoId
this.playerId = playerId
this.clickToPlay = clickToPlay
this.element = document.createElement('div')
this.listeners = {}
}
var counter = 0
$.extend(VimeoPlayer.prototype, {
on: function (type, func) {
this.listeners[type] = func
return this
},
loadAPI: function () {
var that = this
var apiUrl = 'https://f.vimeocdn.com/js/froogaloop2.min.js'
var scriptTags = document.getElementsByTagName('script')
var i = scriptTags.length
var scriptTag
var called
/**
* Callback function
*/
function callback() {
if (!called && that.playOnReady) {
that.play()
}
called = true
}
while (i) {
i -= 1
if (scriptTags[i].src === apiUrl) {
scriptTag = scriptTags[i]
break
}
}
if (!scriptTag) {
scriptTag = document.createElement('script')
scriptTag.src = apiUrl
}
$(scriptTag).on('load', callback)
scriptTags[0].parentNode.insertBefore(scriptTag, scriptTags[0])
// Fix for cached scripts on IE 8:
if (/loaded|complete/.test(scriptTag.readyState)) {
callback()
}
},
onReady: function () {
var that = this
this.ready = true
this.player.addEvent('play', function () {
that.hasPlayed = true
that.onPlaying()
})
this.player.addEvent('pause', function () {
that.onPause()
})
this.player.addEvent('finish', function () {
that.onPause()
})
if (this.playOnReady) {
this.play()
}
},
onPlaying: function () {
if (this.playStatus < 2) {
this.listeners.playing()
this.playStatus = 2
}
},
onPause: function () {
this.listeners.pause()
delete this.playStatus
},
insertIframe: function () {
var iframe = document.createElement('iframe')
iframe.src = this.url
.replace('VIDEO_ID', this.videoId)
.replace('PLAYER_ID', this.playerId)
iframe.id = this.playerId
iframe.allow = 'autoplay'
this.element.parentNode.replaceChild(iframe, this.element)
this.element = iframe
},
play: function () {
var that = this
if (!this.playStatus) {
this.listeners.play()
this.playStatus = 1
}
if (this.ready) {
if (
!this.hasPlayed &&
(this.clickToPlay ||
(window.navigator &&
/iP(hone|od|ad)/.test(window.navigator.platform)))
) {
// Manually trigger the playing callback if clickToPlay
// is enabled and to workaround a limitation in iOS,
// which requires synchronous user interaction to start
// the video playback:
this.onPlaying()
} else {
this.player.api('play')
}
} else {
this.playOnReady = true
if (!window.$f) {
this.loadAPI()
} else if (!this.player) {
this.insertIframe()
this.player = $f(this.element)
this.player.addEvent('ready', function () {
that.onReady()
})
}
}
},
pause: function () {
if (this.ready) {
this.player.api('pause')
} else if (this.playStatus) {
delete this.playOnReady
this.listeners.pause()
delete this.playStatus
}
}
})
$.extend(galleryPrototype, {
VimeoPlayer: VimeoPlayer,
textFactory: function (obj, callback) {
var options = this.options
var videoId = this.getItemProperty(obj, options.vimeoVideoIdProperty)
if (videoId) {
if (this.getItemProperty(obj, options.urlProperty) === undefined) {
obj[options.urlProperty] = 'https://vimeo.com/' + videoId
}
counter += 1
return this.videoFactory(
obj,
callback,
new VimeoPlayer(
options.vimeoPlayerUrl,
videoId,
options.vimeoPlayerIdPrefix + counter,
options.vimeoClickToPlay
)
)
}
return textFactory.call(this, obj, callback)
}
})
return Gallery
})
/*
* blueimp Gallery Vimeo Video Factory JS
* https://github.com/blueimp/Gallery
*
* Copyright 2013, Sebastian Tschan
* https://blueimp.net
*
* Licensed under the MIT license:
* https://opensource.org/licenses/MIT
*/
/* global define, $f */
;(function (factory) {
'use strict'
if (typeof define === 'function' && define.amd) {
// Register as an anonymous AMD module:
define(['./blueimp-helper', './blueimp-gallery-video'], factory)
} else {
// Browser globals:
factory(window.blueimp.helper || window.jQuery, window.blueimp.Gallery)
}
})(function ($, Gallery) {
'use strict'
if (!window.postMessage) {
return Gallery
}
var galleryPrototype = Gallery.prototype
$.extend(galleryPrototype.options, {
// The list object property (or data attribute) with the Vimeo video id:
vimeoVideoIdProperty: 'vimeo',
// The URL for the Vimeo video player, can be extended with custom parameters:
// https://developer.vimeo.com/player/embedding
vimeoPlayerUrl:
'https://player.vimeo.com/video/VIDEO_ID?api=1&player_id=PLAYER_ID',
// The prefix for the Vimeo video player ID:
vimeoPlayerIdPrefix: 'vimeo-player-',
// Require a click on the native Vimeo player for the initial playback:
vimeoClickToPlay: false
})
var textFactory =
galleryPrototype.textFactory || galleryPrototype.imageFactory
var VimeoPlayer = function (url, videoId, playerId, clickToPlay) {
this.url = url
this.videoId = videoId
this.playerId = playerId
this.clickToPlay = clickToPlay
this.element = document.createElement('div')
this.listeners = {}
}
var counter = 0
$.extend(VimeoPlayer.prototype, {
on: function (type, func) {
this.listeners[type] = func
return this
},
loadAPI: function () {
var that = this
var apiUrl = 'https://f.vimeocdn.com/js/froogaloop2.min.js'
var scriptTags = document.getElementsByTagName('script')
var i = scriptTags.length
var scriptTag
var called
/**
* Callback function
*/
function callback() {
if (!called && that.playOnReady) {
that.play()
}
called = true
}
while (i) {
i -= 1
if (scriptTags[i].src === apiUrl) {
scriptTag = scriptTags[i]
break
}
}
if (!scriptTag) {
scriptTag = document.createElement('script')
scriptTag.src = apiUrl
}
$(scriptTag).on('load', callback)
scriptTags[0].parentNode.insertBefore(scriptTag, scriptTags[0])
// Fix for cached scripts on IE 8:
if (/loaded|complete/.test(scriptTag.readyState)) {
callback()
}
},
onReady: function () {
var that = this
this.ready = true
this.player.addEvent('play', function () {
that.hasPlayed = true
that.onPlaying()
})
this.player.addEvent('pause', function () {
that.onPause()
})
this.player.addEvent('finish', function () {
that.onPause()
})
if (this.playOnReady) {
this.play()
}
},
onPlaying: function () {
if (this.playStatus < 2) {
this.listeners.playing()
this.playStatus = 2
}
},
onPause: function () {
this.listeners.pause()
delete this.playStatus
},
insertIframe: function () {
var iframe = document.createElement('iframe')
iframe.src = this.url
.replace('VIDEO_ID', this.videoId)
.replace('PLAYER_ID', this.playerId)
iframe.id = this.playerId
iframe.allow = 'autoplay'
this.element.parentNode.replaceChild(iframe, this.element)
this.element = iframe
},
play: function () {
var that = this
if (!this.playStatus) {
this.listeners.play()
this.playStatus = 1
}
if (this.ready) {
if (
!this.hasPlayed &&
(this.clickToPlay ||
(window.navigator &&
/iP(hone|od|ad)/.test(window.navigator.platform)))
) {
// Manually trigger the playing callback if clickToPlay
// is enabled and to workaround a limitation in iOS,
// which requires synchronous user interaction to start
// the video playback:
this.onPlaying()
} else {
this.player.api('play')
}
} else {
this.playOnReady = true
if (!window.$f) {
this.loadAPI()
} else if (!this.player) {
this.insertIframe()
this.player = $f(this.element)
this.player.addEvent('ready', function () {
that.onReady()
})
}
}
},
pause: function () {
if (this.ready) {
this.player.api('pause')
} else if (this.playStatus) {
delete this.playOnReady
this.listeners.pause()
delete this.playStatus
}
}
})
$.extend(galleryPrototype, {
VimeoPlayer: VimeoPlayer,
textFactory: function (obj, callback) {
var options = this.options
var videoId = this.getItemProperty(obj, options.vimeoVideoIdProperty)
if (videoId) {
if (this.getItemProperty(obj, options.urlProperty) === undefined) {
obj[options.urlProperty] = 'https://vimeo.com/' + videoId
}
counter += 1
return this.videoFactory(
obj,
callback,
new VimeoPlayer(
options.vimeoPlayerUrl,
videoId,
options.vimeoPlayerIdPrefix + counter,
options.vimeoClickToPlay
)
)
}
return textFactory.call(this, obj, callback)
}
})
return Gallery
})

View File

@@ -1,224 +1,224 @@
/*
* blueimp Gallery YouTube Video Factory JS
* https://github.com/blueimp/Gallery
*
* Copyright 2013, Sebastian Tschan
* https://blueimp.net
*
* Licensed under the MIT license:
* https://opensource.org/licenses/MIT
*/
/* global define, YT */
;(function (factory) {
'use strict'
if (typeof define === 'function' && define.amd) {
// Register as an anonymous AMD module:
define(['./blueimp-helper', './blueimp-gallery-video'], factory)
} else {
// Browser globals:
factory(window.blueimp.helper || window.jQuery, window.blueimp.Gallery)
}
})(function ($, Gallery) {
'use strict'
if (!window.postMessage) {
return Gallery
}
var galleryPrototype = Gallery.prototype
$.extend(galleryPrototype.options, {
// The list object property (or data attribute) with the YouTube video id:
youTubeVideoIdProperty: 'youtube',
// Optional object with parameters passed to the YouTube video player:
// https://developers.google.com/youtube/player_parameters
youTubePlayerVars: {
wmode: 'transparent'
},
// Require a click on the native YouTube player for the initial playback:
youTubeClickToPlay: false
})
var textFactory =
galleryPrototype.textFactory || galleryPrototype.imageFactory
var YouTubePlayer = function (videoId, playerVars, clickToPlay) {
this.videoId = videoId
this.playerVars = playerVars
this.clickToPlay = clickToPlay
this.element = document.createElement('div')
this.listeners = {}
}
$.extend(YouTubePlayer.prototype, {
on: function (type, func) {
this.listeners[type] = func
return this
},
loadAPI: function () {
var that = this
var onYouTubeIframeAPIReady = window.onYouTubeIframeAPIReady
var apiUrl = 'https://www.youtube.com/iframe_api'
var scriptTags = document.getElementsByTagName('script')
var i = scriptTags.length
var scriptTag
window.onYouTubeIframeAPIReady = function () {
if (onYouTubeIframeAPIReady) {
onYouTubeIframeAPIReady.apply(this)
}
if (that.playOnReady) {
that.play()
}
}
while (i) {
i -= 1
if (scriptTags[i].src === apiUrl) {
return
}
}
scriptTag = document.createElement('script')
scriptTag.src = apiUrl
scriptTags[0].parentNode.insertBefore(scriptTag, scriptTags[0])
},
onReady: function () {
this.ready = true
if (this.playOnReady) {
this.play()
}
},
onPlaying: function () {
if (this.playStatus < 2) {
this.listeners.playing()
this.playStatus = 2
}
},
onPause: function () {
this.listeners.pause()
delete this.playStatus
},
onStateChange: function (event) {
window.clearTimeout(this.pauseTimeout)
switch (event.data) {
case YT.PlayerState.PLAYING:
this.hasPlayed = true
this.onPlaying()
break
case YT.PlayerState.UNSTARTED:
case YT.PlayerState.PAUSED:
// YouTube sends an unstarted event if pause is triggered before the
// video has started.
// YouTube sends a pause event when seeking.
// In both cases, we initiate a pause in a timeout that gets cleared
// if followed by another event within the timeout window.
this.pauseTimeout = galleryPrototype.setTimeout.call(
this,
this.onPause,
null,
500
)
break
case YT.PlayerState.ENDED:
this.onPause()
break
}
},
onError: function (event) {
this.listeners.error(event)
},
play: function () {
var that = this
if (!this.playStatus) {
this.listeners.play()
this.playStatus = 1
}
if (this.ready) {
if (
!this.hasPlayed &&
(this.clickToPlay ||
(window.navigator &&
/iP(hone|od|ad)/.test(window.navigator.platform)))
) {
// Manually trigger the playing callback if clickToPlay
// is enabled and to workaround a limitation in iOS,
// which requires synchronous user interaction to start
// the video playback:
this.onPlaying()
} else {
this.player.playVideo()
}
} else {
this.playOnReady = true
if (!(window.YT && YT.Player)) {
this.loadAPI()
} else if (!this.player) {
this.player = new YT.Player(this.element, {
videoId: this.videoId,
playerVars: this.playerVars,
events: {
onReady: function () {
that.onReady()
},
onStateChange: function (event) {
that.onStateChange(event)
},
onError: function (event) {
that.onError(event)
}
}
})
}
}
},
pause: function () {
if (this.ready) {
this.player.pauseVideo()
} else if (this.playStatus) {
delete this.playOnReady
this.listeners.pause()
delete this.playStatus
}
}
})
$.extend(galleryPrototype, {
YouTubePlayer: YouTubePlayer,
textFactory: function (obj, callback) {
var options = this.options
var videoId = this.getItemProperty(obj, options.youTubeVideoIdProperty)
if (videoId) {
if (this.getItemProperty(obj, options.urlProperty) === undefined) {
obj[options.urlProperty] =
'https://www.youtube.com/watch?v=' + videoId
}
if (
this.getItemProperty(obj, options.videoPosterProperty) === undefined
) {
obj[options.videoPosterProperty] =
'https://img.youtube.com/vi/' + videoId + '/maxresdefault.jpg'
}
return this.videoFactory(
obj,
callback,
new YouTubePlayer(
videoId,
options.youTubePlayerVars,
options.youTubeClickToPlay
)
)
}
return textFactory.call(this, obj, callback)
}
})
return Gallery
})
/*
* blueimp Gallery YouTube Video Factory JS
* https://github.com/blueimp/Gallery
*
* Copyright 2013, Sebastian Tschan
* https://blueimp.net
*
* Licensed under the MIT license:
* https://opensource.org/licenses/MIT
*/
/* global define, YT */
;(function (factory) {
'use strict'
if (typeof define === 'function' && define.amd) {
// Register as an anonymous AMD module:
define(['./blueimp-helper', './blueimp-gallery-video'], factory)
} else {
// Browser globals:
factory(window.blueimp.helper || window.jQuery, window.blueimp.Gallery)
}
})(function ($, Gallery) {
'use strict'
if (!window.postMessage) {
return Gallery
}
var galleryPrototype = Gallery.prototype
$.extend(galleryPrototype.options, {
// The list object property (or data attribute) with the YouTube video id:
youTubeVideoIdProperty: 'youtube',
// Optional object with parameters passed to the YouTube video player:
// https://developers.google.com/youtube/player_parameters
youTubePlayerVars: {
wmode: 'transparent'
},
// Require a click on the native YouTube player for the initial playback:
youTubeClickToPlay: false
})
var textFactory =
galleryPrototype.textFactory || galleryPrototype.imageFactory
var YouTubePlayer = function (videoId, playerVars, clickToPlay) {
this.videoId = videoId
this.playerVars = playerVars
this.clickToPlay = clickToPlay
this.element = document.createElement('div')
this.listeners = {}
}
$.extend(YouTubePlayer.prototype, {
on: function (type, func) {
this.listeners[type] = func
return this
},
loadAPI: function () {
var that = this
var onYouTubeIframeAPIReady = window.onYouTubeIframeAPIReady
var apiUrl = 'https://www.youtube.com/iframe_api'
var scriptTags = document.getElementsByTagName('script')
var i = scriptTags.length
var scriptTag
window.onYouTubeIframeAPIReady = function () {
if (onYouTubeIframeAPIReady) {
onYouTubeIframeAPIReady.apply(this)
}
if (that.playOnReady) {
that.play()
}
}
while (i) {
i -= 1
if (scriptTags[i].src === apiUrl) {
return
}
}
scriptTag = document.createElement('script')
scriptTag.src = apiUrl
scriptTags[0].parentNode.insertBefore(scriptTag, scriptTags[0])
},
onReady: function () {
this.ready = true
if (this.playOnReady) {
this.play()
}
},
onPlaying: function () {
if (this.playStatus < 2) {
this.listeners.playing()
this.playStatus = 2
}
},
onPause: function () {
this.listeners.pause()
delete this.playStatus
},
onStateChange: function (event) {
window.clearTimeout(this.pauseTimeout)
switch (event.data) {
case YT.PlayerState.PLAYING:
this.hasPlayed = true
this.onPlaying()
break
case YT.PlayerState.UNSTARTED:
case YT.PlayerState.PAUSED:
// YouTube sends an unstarted event if pause is triggered before the
// video has started.
// YouTube sends a pause event when seeking.
// In both cases, we initiate a pause in a timeout that gets cleared
// if followed by another event within the timeout window.
this.pauseTimeout = galleryPrototype.setTimeout.call(
this,
this.onPause,
null,
500
)
break
case YT.PlayerState.ENDED:
this.onPause()
break
}
},
onError: function (event) {
this.listeners.error(event)
},
play: function () {
var that = this
if (!this.playStatus) {
this.listeners.play()
this.playStatus = 1
}
if (this.ready) {
if (
!this.hasPlayed &&
(this.clickToPlay ||
(window.navigator &&
/iP(hone|od|ad)/.test(window.navigator.platform)))
) {
// Manually trigger the playing callback if clickToPlay
// is enabled and to workaround a limitation in iOS,
// which requires synchronous user interaction to start
// the video playback:
this.onPlaying()
} else {
this.player.playVideo()
}
} else {
this.playOnReady = true
if (!(window.YT && YT.Player)) {
this.loadAPI()
} else if (!this.player) {
this.player = new YT.Player(this.element, {
videoId: this.videoId,
playerVars: this.playerVars,
events: {
onReady: function () {
that.onReady()
},
onStateChange: function (event) {
that.onStateChange(event)
},
onError: function (event) {
that.onError(event)
}
}
})
}
}
},
pause: function () {
if (this.ready) {
this.player.pauseVideo()
} else if (this.playStatus) {
delete this.playOnReady
this.listeners.pause()
delete this.playStatus
}
}
})
$.extend(galleryPrototype, {
YouTubePlayer: YouTubePlayer,
textFactory: function (obj, callback) {
var options = this.options
var videoId = this.getItemProperty(obj, options.youTubeVideoIdProperty)
if (videoId) {
if (this.getItemProperty(obj, options.urlProperty) === undefined) {
obj[options.urlProperty] =
'https://www.youtube.com/watch?v=' + videoId
}
if (
this.getItemProperty(obj, options.videoPosterProperty) === undefined
) {
obj[options.videoPosterProperty] =
'https://img.youtube.com/vi/' + videoId + '/maxresdefault.jpg'
}
return this.videoFactory(
obj,
callback,
new YouTubePlayer(
videoId,
options.youTubePlayerVars,
options.youTubeClickToPlay
)
)
}
return textFactory.call(this, obj, callback)
}
})
return Gallery
})

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,217 +1,217 @@
/*
* blueimp helper JS
* https://github.com/blueimp/Gallery
*
* Copyright 2013, Sebastian Tschan
* https://blueimp.net
*
* Licensed under the MIT license:
* https://opensource.org/licenses/MIT
*/
/* global define */
/* eslint-disable no-param-reassign */
;(function () {
'use strict'
/**
* Object.assign polyfill
*
* @param {object} obj1 First object
* @param {object} obj2 Second object
* @returns {object} Merged object
*/
function extend(obj1, obj2) {
var prop
for (prop in obj2) {
if (Object.prototype.hasOwnProperty.call(obj2, prop)) {
obj1[prop] = obj2[prop]
}
}
return obj1
}
/**
* Helper constructor
*
* @class
* @param {*} query jQuery type query argument
*/
function Helper(query) {
if (!this || this.find !== Helper.prototype.find) {
// Called as function instead of as constructor,
// so we simply return a new instance:
return new Helper(query)
}
this.length = 0
if (query) {
if (typeof query === 'string') {
query = this.find(query)
}
if (query.nodeType || query === query.window) {
// Single HTML element
this.length = 1
this[0] = query
} else {
// HTML element collection
var i = query.length
this.length = i
while (i) {
i -= 1
this[i] = query[i]
}
}
}
}
Helper.extend = extend
Helper.contains = function (container, element) {
do {
element = element.parentNode
if (element === container) {
return true
}
} while (element)
return false
}
Helper.parseJSON = function (string) {
return JSON.parse(string)
}
extend(Helper.prototype, {
find: function (query) {
var container = this[0] || document
if (typeof query === 'string') {
if (container.querySelectorAll) {
query = container.querySelectorAll(query)
} else if (query.charAt(0) === '#') {
query = container.getElementById(query.slice(1))
} else {
query = container.getElementsByTagName(query)
}
}
return new Helper(query)
},
hasClass: function (className) {
if (!this[0]) return false
return new RegExp('(?:^|\\s+)' + className + '(?:\\s+|$)').test(
this[0].className
)
},
addClass: function (className) {
var i = this.length
var classNames
var element
var j
while (i) {
i -= 1
element = this[i]
if (!element.className) {
element.className = className
continue
}
if (!classNames) classNames = className.split(/\s+/)
for (j = 0; j < classNames.length; j += 1) {
if (this.hasClass(classNames[j])) {
continue
}
element.className += ' ' + classNames[j]
}
}
return this
},
removeClass: function (className) {
// Match any of the given class names
var regexp = new RegExp('^(?:' + className.split(/\s+/).join('|') + ')$')
// Match any class names and their trailing whitespace
var matcher = /(\S+)(?:\s+|$)/g
var replacer = function (match, className) {
// Replace class names that match the given ones
return regexp.test(className) ? '' : match
}
var trimEnd = /\s+$/
var i = this.length
var element
while (i) {
i -= 1
element = this[i]
element.className = element.className
.replace(matcher, replacer)
.replace(trimEnd, '')
}
return this
},
on: function (eventName, handler) {
var eventNames = eventName.split(/\s+/)
var i
var element
while (eventNames.length) {
eventName = eventNames.shift()
i = this.length
while (i) {
i -= 1
element = this[i]
if (element.addEventListener) {
element.addEventListener(eventName, handler, false)
} else if (element.attachEvent) {
element.attachEvent('on' + eventName, handler)
}
}
}
return this
},
off: function (eventName, handler) {
var eventNames = eventName.split(/\s+/)
var i
var element
while (eventNames.length) {
eventName = eventNames.shift()
i = this.length
while (i) {
i -= 1
element = this[i]
if (element.removeEventListener) {
element.removeEventListener(eventName, handler, false)
} else if (element.detachEvent) {
element.detachEvent('on' + eventName, handler)
}
}
}
return this
},
empty: function () {
var i = this.length
var element
while (i) {
i -= 1
element = this[i]
while (element.hasChildNodes()) {
element.removeChild(element.lastChild)
}
}
return this
},
first: function () {
return new Helper(this[0])
}
})
if (typeof define === 'function' && define.amd) {
define(function () {
return Helper
})
} else {
window.blueimp = window.blueimp || {}
window.blueimp.helper = Helper
}
})()
/*
* blueimp helper JS
* https://github.com/blueimp/Gallery
*
* Copyright 2013, Sebastian Tschan
* https://blueimp.net
*
* Licensed under the MIT license:
* https://opensource.org/licenses/MIT
*/
/* global define */
/* eslint-disable no-param-reassign */
;(function () {
'use strict'
/**
* Object.assign polyfill
*
* @param {object} obj1 First object
* @param {object} obj2 Second object
* @returns {object} Merged object
*/
function extend(obj1, obj2) {
var prop
for (prop in obj2) {
if (Object.prototype.hasOwnProperty.call(obj2, prop)) {
obj1[prop] = obj2[prop]
}
}
return obj1
}
/**
* Helper constructor
*
* @class
* @param {*} query jQuery type query argument
*/
function Helper(query) {
if (!this || this.find !== Helper.prototype.find) {
// Called as function instead of as constructor,
// so we simply return a new instance:
return new Helper(query)
}
this.length = 0
if (query) {
if (typeof query === 'string') {
query = this.find(query)
}
if (query.nodeType || query === query.window) {
// Single HTML element
this.length = 1
this[0] = query
} else {
// HTML element collection
var i = query.length
this.length = i
while (i) {
i -= 1
this[i] = query[i]
}
}
}
}
Helper.extend = extend
Helper.contains = function (container, element) {
do {
element = element.parentNode
if (element === container) {
return true
}
} while (element)
return false
}
Helper.parseJSON = function (string) {
return JSON.parse(string)
}
extend(Helper.prototype, {
find: function (query) {
var container = this[0] || document
if (typeof query === 'string') {
if (container.querySelectorAll) {
query = container.querySelectorAll(query)
} else if (query.charAt(0) === '#') {
query = container.getElementById(query.slice(1))
} else {
query = container.getElementsByTagName(query)
}
}
return new Helper(query)
},
hasClass: function (className) {
if (!this[0]) return false
return new RegExp('(?:^|\\s+)' + className + '(?:\\s+|$)').test(
this[0].className
)
},
addClass: function (className) {
var i = this.length
var classNames
var element
var j
while (i) {
i -= 1
element = this[i]
if (!element.className) {
element.className = className
continue
}
if (!classNames) classNames = className.split(/\s+/)
for (j = 0; j < classNames.length; j += 1) {
if (this.hasClass(classNames[j])) {
continue
}
element.className += ' ' + classNames[j]
}
}
return this
},
removeClass: function (className) {
// Match any of the given class names
var regexp = new RegExp('^(?:' + className.split(/\s+/).join('|') + ')$')
// Match any class names and their trailing whitespace
var matcher = /(\S+)(?:\s+|$)/g
var replacer = function (match, className) {
// Replace class names that match the given ones
return regexp.test(className) ? '' : match
}
var trimEnd = /\s+$/
var i = this.length
var element
while (i) {
i -= 1
element = this[i]
element.className = element.className
.replace(matcher, replacer)
.replace(trimEnd, '')
}
return this
},
on: function (eventName, handler) {
var eventNames = eventName.split(/\s+/)
var i
var element
while (eventNames.length) {
eventName = eventNames.shift()
i = this.length
while (i) {
i -= 1
element = this[i]
if (element.addEventListener) {
element.addEventListener(eventName, handler, false)
} else if (element.attachEvent) {
element.attachEvent('on' + eventName, handler)
}
}
}
return this
},
off: function (eventName, handler) {
var eventNames = eventName.split(/\s+/)
var i
var element
while (eventNames.length) {
eventName = eventNames.shift()
i = this.length
while (i) {
i -= 1
element = this[i]
if (element.removeEventListener) {
element.removeEventListener(eventName, handler, false)
} else if (element.detachEvent) {
element.detachEvent('on' + eventName, handler)
}
}
}
return this
},
empty: function () {
var i = this.length
var element
while (i) {
i -= 1
element = this[i]
while (element.hasChildNodes()) {
element.removeChild(element.lastChild)
}
}
return this
},
first: function () {
return new Helper(this[0])
}
})
if (typeof define === 'function' && define.amd) {
define(function () {
return Helper
})
} else {
window.blueimp = window.blueimp || {}
window.blueimp.helper = Helper
}
})()

View File

@@ -1,140 +1,140 @@
/*
* blueimp Gallery Demo JS
* https://github.com/blueimp/Gallery
*
* Copyright 2013, Sebastian Tschan
* https://blueimp.net
*
* Licensed under the MIT license:
* https://opensource.org/licenses/MIT
*/
/* global blueimp, $ */
$(function () {
'use strict'
// Flickr image types:
var imageTypes = [
// https://www.flickr.com/services/api/misc.urls.html
'sq', // 75x75
'q', // 150x150
't', // 100 on longest side
's', // 240 on longest side
'n', // 320 on longest side
'm', // 500 on longest side
'z', // 640 on longest side
'c', // 800 on longest side
'l', // 1024 on longest side
'h', // 1600 on longest side
'k', // 2048 on longest side
'o' // original dimensions
]
// Load demo images from Flickr:
$.ajax({
url: 'https://api.flickr.com/services/rest/',
data: {
// https://www.flickr.com/services/api/flickr.interestingness.getList.html
method: 'flickr.interestingness.getList',
format: 'json',
extras: 'url_' + imageTypes.join(',url_'),
// eslint-disable-next-line camelcase
api_key: '7617adae70159d09ba78cfec73c13be3'
},
dataType: 'jsonp',
jsonp: 'jsoncallback'
}).done(function (result) {
var maxWidth = $(document.body).css('max-width')
var sizes = '(min-width: ' + maxWidth + ') ' + maxWidth + ', 100vw'
var carouselLinks = []
var linksContainer = $('#links')
// Add the demo images as links with thumbnails to the page:
$.each(result.photos.photo, function (_, photo) {
var thumbnail = $('<img>')
.prop('loading', 'lazy')
.prop('width', photo.width_sq)
.prop('height', photo.height_sq)
.prop('src', photo.url_sq)
.prop('alt', photo.title)
var srcset = []
$.each(imageTypes, function (_, type) {
var url = photo['url_' + type]
var width = photo['width_' + type]
if (url) {
srcset.push(url + ' ' + width + 'w')
}
})
srcset = srcset.join(',')
$('<a></a>')
.append(thumbnail)
.prop('title', photo.title)
.prop('href', photo.url_l)
.attr('data-srcset', srcset)
.attr('data-gallery', '')
.appendTo(linksContainer)
carouselLinks.push({
title: photo.title,
href: photo.url_l,
sizes: sizes,
srcset: srcset
})
})
// Initialize the Gallery as image carousel:
// eslint-disable-next-line new-cap
blueimp.Gallery(carouselLinks, {
container: '#blueimp-image-carousel',
carousel: true
})
})
// Initialize the Gallery as video carousel:
// eslint-disable-next-line new-cap
blueimp.Gallery(
[
{
title: 'Sintel',
type: 'video',
sources: [
{
type: 'video/webm',
src:
'https://upload.wikimedia.org/wikipedia/commons/f/f1/' +
'Sintel_movie_4K.webm'
},
{
type: 'video/mp4',
src: 'https://archive.org/download/Sintel/sintel-2048-surround.mp4'
},
{
type: 'video/ogg',
src: 'https://archive.org/download/Sintel/sintel-2048-stereo.ogv'
}
],
poster:
'https://upload.wikimedia.org/wikipedia/commons/d/dc/' +
'Sintel_1920x1080.png'
},
{
title: 'LES TWINS - An Industry Ahead',
type: 'text/html',
youtube: 'zi4CIXpx7Bg'
},
{
title: 'KN1GHT - Last Moon',
type: 'text/html',
vimeo: '73686146',
poster: 'https://secure-a.vimeocdn.com/ts/448/835/448835699_960.jpg'
}
],
{
container: '#blueimp-video-carousel',
carousel: true,
startSlideshow: false
}
)
$('#fullscreen').change(function () {
$('#blueimp-gallery').data('fullscreen', this.checked)
})
})
/*
* blueimp Gallery Demo JS
* https://github.com/blueimp/Gallery
*
* Copyright 2013, Sebastian Tschan
* https://blueimp.net
*
* Licensed under the MIT license:
* https://opensource.org/licenses/MIT
*/
/* global blueimp, $ */
$(function () {
'use strict'
// Flickr image types:
var imageTypes = [
// https://www.flickr.com/services/api/misc.urls.html
'sq', // 75x75
'q', // 150x150
't', // 100 on longest side
's', // 240 on longest side
'n', // 320 on longest side
'm', // 500 on longest side
'z', // 640 on longest side
'c', // 800 on longest side
'l', // 1024 on longest side
'h', // 1600 on longest side
'k', // 2048 on longest side
'o' // original dimensions
]
// Load demo images from Flickr:
$.ajax({
url: 'https://api.flickr.com/services/rest/',
data: {
// https://www.flickr.com/services/api/flickr.interestingness.getList.html
method: 'flickr.interestingness.getList',
format: 'json',
extras: 'url_' + imageTypes.join(',url_'),
// eslint-disable-next-line camelcase
api_key: '7617adae70159d09ba78cfec73c13be3'
},
dataType: 'jsonp',
jsonp: 'jsoncallback'
}).done(function (result) {
var maxWidth = $(document.body).css('max-width')
var sizes = '(min-width: ' + maxWidth + ') ' + maxWidth + ', 100vw'
var carouselLinks = []
var linksContainer = $('#links')
// Add the demo images as links with thumbnails to the page:
$.each(result.photos.photo, function (_, photo) {
var thumbnail = $('<img>')
.prop('loading', 'lazy')
.prop('width', photo.width_sq)
.prop('height', photo.height_sq)
.prop('src', photo.url_sq)
.prop('alt', photo.title)
var srcset = []
$.each(imageTypes, function (_, type) {
var url = photo['url_' + type]
var width = photo['width_' + type]
if (url) {
srcset.push(url + ' ' + width + 'w')
}
})
srcset = srcset.join(',')
$('<a></a>')
.append(thumbnail)
.prop('title', photo.title)
.prop('href', photo.url_l)
.attr('data-srcset', srcset)
.attr('data-gallery', '')
.appendTo(linksContainer)
carouselLinks.push({
title: photo.title,
href: photo.url_l,
sizes: sizes,
srcset: srcset
})
})
// Initialize the Gallery as image carousel:
// eslint-disable-next-line new-cap
blueimp.Gallery(carouselLinks, {
container: '#blueimp-image-carousel',
carousel: true
})
})
// Initialize the Gallery as video carousel:
// eslint-disable-next-line new-cap
blueimp.Gallery(
[
{
title: 'Sintel',
type: 'video',
sources: [
{
type: 'video/webm',
src:
'https://upload.wikimedia.org/wikipedia/commons/f/f1/' +
'Sintel_movie_4K.webm'
},
{
type: 'video/mp4',
src: 'https://archive.org/download/Sintel/sintel-2048-surround.mp4'
},
{
type: 'video/ogg',
src: 'https://archive.org/download/Sintel/sintel-2048-stereo.ogv'
}
],
poster:
'https://upload.wikimedia.org/wikipedia/commons/d/dc/' +
'Sintel_1920x1080.png'
},
{
title: 'LES TWINS - An Industry Ahead',
type: 'text/html',
youtube: 'zi4CIXpx7Bg'
},
{
title: 'KN1GHT - Last Moon',
type: 'text/html',
vimeo: '73686146',
poster: 'https://secure-a.vimeocdn.com/ts/448/835/448835699_960.jpg'
}
],
{
container: '#blueimp-video-carousel',
carousel: true,
startSlideshow: false
}
)
$('#fullscreen').change(function () {
$('#blueimp-gallery').data('fullscreen', this.checked)
})
})

View File

@@ -1,75 +1,75 @@
/*
* blueimp Gallery jQuery plugin
* https://github.com/blueimp/Gallery
*
* Copyright 2013, Sebastian Tschan
* https://blueimp.net
*
* Licensed under the MIT license:
* https://opensource.org/licenses/MIT
*/
/* global define */
;(function (factory) {
'use strict'
if (typeof define === 'function' && define.amd) {
define(['jquery', './blueimp-gallery'], factory)
} else {
factory(window.jQuery, window.blueimp.Gallery)
}
})(function ($, Gallery) {
'use strict'
// Global click handler to open links with data-gallery attribute
// in the Gallery lightbox:
$(document).on('click', '[data-gallery]', function (event) {
// Get the container id from the data-gallery attribute:
var id = $(this).data('gallery')
var widget = $(id)
var container =
(widget.length && widget) || $(Gallery.prototype.options.container)
var callbacks = {
onopen: function () {
container.data('gallery', this).trigger('open')
},
onopened: function () {
container.trigger('opened')
},
onslide: function () {
container.trigger('slide', arguments)
},
onslideend: function () {
container.trigger('slideend', arguments)
},
onslidecomplete: function () {
container.trigger('slidecomplete', arguments)
},
onclose: function () {
container.trigger('close')
},
onclosed: function () {
container.trigger('closed').removeData('gallery')
}
}
var options = $.extend(
// Retrieve custom options from data-attributes
// on the Gallery widget:
container.data(),
{
container: container[0],
index: this,
event: event
},
callbacks
)
// Select all links with the same data-gallery attribute:
var links = $(this)
.closest('[data-gallery-group], body')
.find('[data-gallery="' + id + '"]')
if (options.filter) {
links = links.filter(options.filter)
}
return new Gallery(links, options)
})
})
/*
* blueimp Gallery jQuery plugin
* https://github.com/blueimp/Gallery
*
* Copyright 2013, Sebastian Tschan
* https://blueimp.net
*
* Licensed under the MIT license:
* https://opensource.org/licenses/MIT
*/
/* global define */
;(function (factory) {
'use strict'
if (typeof define === 'function' && define.amd) {
define(['jquery', './blueimp-gallery'], factory)
} else {
factory(window.jQuery, window.blueimp.Gallery)
}
})(function ($, Gallery) {
'use strict'
// Global click handler to open links with data-gallery attribute
// in the Gallery lightbox:
$(document).on('click', '[data-gallery]', function (event) {
// Get the container id from the data-gallery attribute:
var id = $(this).data('gallery')
var widget = $(id)
var container =
(widget.length && widget) || $(Gallery.prototype.options.container)
var callbacks = {
onopen: function () {
container.data('gallery', this).trigger('open')
},
onopened: function () {
container.trigger('opened')
},
onslide: function () {
container.trigger('slide', arguments)
},
onslideend: function () {
container.trigger('slideend', arguments)
},
onslidecomplete: function () {
container.trigger('slidecomplete', arguments)
},
onclose: function () {
container.trigger('close')
},
onclosed: function () {
container.trigger('closed').removeData('gallery')
}
}
var options = $.extend(
// Retrieve custom options from data-attributes
// on the Gallery widget:
container.data(),
{
container: container[0],
index: this,
event: event
},
callbacks
)
// Select all links with the same data-gallery attribute:
var links = $(this)
.closest('[data-gallery-group], body')
.find('[data-gallery="' + id + '"]')
if (options.filter) {
links = links.filter(options.filter)
}
return new Gallery(links, options)
})
})

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

6768
assets/Gallery-3.4.0/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,98 +1,100 @@
{
"name": "blueimp-gallery",
"version": "3.3.0",
"title": "blueimp Gallery",
"description": "blueimp Gallery is a touch-enabled, responsive and customizable image and video gallery, carousel and lightbox, optimized for both mobile and desktop web browsers. It features swipe, mouse and keyboard navigation, transition effects, slideshow functionality, fullscreen support and on-demand content loading and can be extended to display additional content types.",
"keywords": [
"image",
"video",
"gallery",
"carousel",
"lightbox",
"mobile",
"desktop",
"touch",
"responsive",
"swipe",
"mouse",
"keyboard",
"navigation",
"transition",
"effects",
"slideshow",
"fullscreen"
],
"homepage": "https://github.com/blueimp/Gallery",
"author": {
"name": "Sebastian Tschan",
"url": "https://blueimp.net"
},
"repository": {
"type": "git",
"url": "git://github.com/blueimp/Gallery.git"
},
"license": "MIT",
"devDependencies": {
"clean-css-cli": "4",
"eslint": "7",
"eslint-config-blueimp": "2",
"eslint-config-prettier": "6",
"eslint-plugin-jsdoc": "30",
"eslint-plugin-prettier": "3",
"prettier": "2",
"stylelint": "13",
"stylelint-config-prettier": "8",
"stylelint-config-recommended": "3",
"uglify-js": "3"
},
"stylelint": {
"extends": [
"stylelint-config-recommended",
"stylelint-config-prettier"
],
"ignoreFiles": [
"css/*.min.css"
]
},
"eslintConfig": {
"extends": [
"blueimp",
"plugin:jsdoc/recommended",
"plugin:prettier/recommended"
],
"env": {
"browser": true
}
},
"eslintIgnore": [
"js/*.min.js",
"js/vendor"
],
"prettier": {
"arrowParens": "avoid",
"proseWrap": "always",
"semi": false,
"singleQuote": true,
"trailingComma": "none"
},
"scripts": {
"test": "stylelint '**/*.css' && eslint .",
"build:js": "cd js && uglifyjs blueimp-helper.js blueimp-gallery.js blueimp-gallery-fullscreen.js blueimp-gallery-indicator.js blueimp-gallery-video.js blueimp-gallery-vimeo.js blueimp-gallery-youtube.js --ie8 -c -m -o blueimp-gallery.min.js --source-map url=blueimp-gallery.min.js.map",
"build:jquery": "cd js && uglifyjs blueimp-gallery.js blueimp-gallery-fullscreen.js blueimp-gallery-indicator.js blueimp-gallery-video.js blueimp-gallery-vimeo.js blueimp-gallery-youtube.js jquery.blueimp-gallery.js --ie8 -c -m -o jquery.blueimp-gallery.min.js --source-map url=jquery.blueimp-gallery.min.js.map",
"build:css": "cd css && cleancss -c ie7 --source-map -o blueimp-gallery.min.css blueimp-gallery.css blueimp-gallery-indicator.css blueimp-gallery-video.css",
"build": "npm run build:js && npm run build:jquery && npm run build:css",
"preversion": "npm test",
"version": "npm run build && git add -A js css",
"postversion": "git push --tags origin master master:gh-pages && npm publish"
},
"files": [
"css/*.css",
"css/*.css.map",
"img/*.gif",
"img/*.png",
"img/*.svg",
"js/*.js",
"js/*.js.map"
],
"main": "js/blueimp-gallery.js"
}
{
"name": "blueimp-gallery",
"version": "3.4.0",
"title": "blueimp Gallery",
"description": "blueimp Gallery is a touch-enabled, responsive and customizable image and video gallery, carousel and lightbox, optimized for both mobile and desktop web browsers. It features swipe, mouse and keyboard navigation, transition effects, slideshow functionality, fullscreen support and on-demand content loading and can be extended to display additional content types.",
"keywords": [
"image",
"video",
"gallery",
"carousel",
"lightbox",
"mobile",
"desktop",
"touch",
"responsive",
"swipe",
"mouse",
"keyboard",
"navigation",
"transition",
"effects",
"slideshow",
"fullscreen"
],
"homepage": "https://github.com/blueimp/Gallery",
"author": {
"name": "Sebastian Tschan",
"url": "https://blueimp.net"
},
"repository": {
"type": "git",
"url": "git://github.com/blueimp/Gallery.git"
},
"license": "MIT",
"devDependencies": {
"clean-css-cli": "5",
"eslint": "7",
"eslint-config-blueimp": "2",
"eslint-config-prettier": "8",
"eslint-plugin-jsdoc": "36",
"eslint-plugin-prettier": "4",
"jquery": "1",
"prettier": "2",
"stylelint": "13",
"stylelint-config-prettier": "8",
"stylelint-config-recommended": "5",
"uglify-js": "3"
},
"stylelint": {
"extends": [
"stylelint-config-recommended",
"stylelint-config-prettier"
],
"ignoreFiles": [
"css/*.min.css"
]
},
"eslintConfig": {
"extends": [
"blueimp",
"plugin:jsdoc/recommended",
"plugin:prettier/recommended"
],
"env": {
"browser": true
}
},
"eslintIgnore": [
"js/*.min.js",
"js/vendor"
],
"prettier": {
"arrowParens": "avoid",
"proseWrap": "always",
"semi": false,
"singleQuote": true,
"trailingComma": "none"
},
"scripts": {
"test": "stylelint '**/*.css' && eslint .",
"prebuild": "bin/sync-vendor-libs.sh",
"build:js": "cd js && uglifyjs blueimp-helper.js blueimp-gallery.js blueimp-gallery-fullscreen.js blueimp-gallery-indicator.js blueimp-gallery-video.js blueimp-gallery-vimeo.js blueimp-gallery-youtube.js --ie8 -c -m -o blueimp-gallery.min.js --source-map url=blueimp-gallery.min.js.map",
"build:jquery": "cd js && uglifyjs blueimp-gallery.js blueimp-gallery-fullscreen.js blueimp-gallery-indicator.js blueimp-gallery-video.js blueimp-gallery-vimeo.js blueimp-gallery-youtube.js jquery.blueimp-gallery.js --ie8 -c -m -o jquery.blueimp-gallery.min.js --source-map url=jquery.blueimp-gallery.min.js.map",
"build:css": "cd css && cleancss -c ie7 --source-map -o blueimp-gallery.min.css blueimp-gallery.css blueimp-gallery-indicator.css blueimp-gallery-video.css",
"build": "npm run build:js && npm run build:jquery && npm run build:css",
"preversion": "npm test",
"version": "npm run build && git add -A js css",
"postversion": "git push --tags origin master master:gh-pages && npm publish"
},
"files": [
"css/*.css",
"css/*.css.map",
"img/*.gif",
"img/*.png",
"img/*.svg",
"js/*.js",
"js/*.js.map"
],
"main": "js/blueimp-gallery.js"
}

View File

@@ -273,3 +273,7 @@ select.admin-autocomplete {
display: block;
padding: 6px;
}
.errors .select2-selection {
border: 1px solid var(--error-fg);
}

View File

@@ -2,93 +2,91 @@
DJANGO Admin styles
*/
@import url(fonts.css);
/* VARIABLE DEFINITIONS */
html[data-theme="light"],
:root {
--primary: #79aec8;
--secondary: #417690;
--accent: #f5dd5d;
--primary-fg: #fff;
--primary: #79aec8;
--secondary: #417690;
--accent: #f5dd5d;
--primary-fg: #fff;
--body-fg: #333;
--body-bg: #fff;
--body-quiet-color: #666;
--body-loud-color: #000;
--body-fg: #333;
--body-bg: #fff;
--body-quiet-color: #666;
--body-medium-color: #444;
--body-loud-color: #000;
--header-color: #ffc;
--header-branding-color: var(--accent);
--header-bg: var(--secondary);
--header-link-color: var(--primary-fg);
--header-color: #ffc;
--header-branding-color: var(--accent);
--header-bg: var(--secondary);
--header-link-color: var(--primary-fg);
--breadcrumbs-fg: #c4dce8;
--breadcrumbs-link-fg: var(--body-bg);
--breadcrumbs-bg: var(--primary);
--breadcrumbs-fg: #c4dce8;
--breadcrumbs-link-fg: var(--body-bg);
--breadcrumbs-bg: #264b5d;
--link-fg: #447e9b;
--link-hover-color: #036;
--link-selected-fg: #5b80b2;
--link-fg: #417893;
--link-hover-color: #036;
--link-selected-fg: var(--secondary);
--hairline-color: #e8e8e8;
--border-color: #ccc;
--hairline-color: #e8e8e8;
--border-color: #ccc;
--error-fg: #ba2121;
--error-fg: #ba2121;
--message-success-bg: #dfd;
--message-warning-bg: #ffc;
--message-error-bg: #ffefef;
--message-success-bg: #dfd;
--message-warning-bg: #ffc;
--message-error-bg: #ffefef;
--darkened-bg: #f8f8f8; /* A bit darker than --body-bg */
--selected-bg: #e4e4e4; /* E.g. selected table cells */
--selected-row: #ffc;
--darkened-bg: #f8f8f8; /* A bit darker than --body-bg */
--selected-bg: #e4e4e4; /* E.g. selected table cells */
--selected-row: #ffc;
--button-fg: #fff;
--button-bg: var(--primary);
--button-hover-bg: #609ab6;
--default-button-bg: var(--secondary);
--default-button-hover-bg: #205067;
--close-button-bg: #888; /* Previously #bbb, contrast 1.92 */
--close-button-hover-bg: #747474;
--delete-button-bg: #ba2121;
--delete-button-hover-bg: #a41515;
--button-fg: #fff;
--button-bg: var(--secondary);
--button-hover-bg: #205067;
--default-button-bg: #205067;
--default-button-hover-bg: var(--secondary);
--close-button-bg: #747474;
--close-button-hover-bg: #333;
--delete-button-bg: #ba2121;
--delete-button-hover-bg: #a41515;
--object-tools-fg: var(--button-fg);
--object-tools-bg: var(--close-button-bg);
--object-tools-hover-bg: var(--close-button-hover-bg);
}
--object-tools-fg: var(--button-fg);
--object-tools-bg: var(--close-button-bg);
--object-tools-hover-bg: var(--close-button-hover-bg);
@media (prefers-color-scheme: dark) {
:root {
--primary: #264b5d;
--primary-fg: #eee;
--font-family-primary:
"Segoe UI",
system-ui,
Roboto,
"Helvetica Neue",
Arial,
sans-serif,
"Apple Color Emoji",
"Segoe UI Emoji",
"Segoe UI Symbol",
"Noto Color Emoji";
--font-family-monospace:
ui-monospace,
Menlo,
Monaco,
"Cascadia Mono",
"Segoe UI Mono",
"Roboto Mono",
"Oxygen Mono",
"Ubuntu Monospace",
"Source Code Pro",
"Fira Mono",
"Droid Sans Mono",
"Courier New",
monospace,
"Apple Color Emoji",
"Segoe UI Emoji",
"Segoe UI Symbol",
"Noto Color Emoji";
--body-fg: #eeeeee;
--body-bg: #121212;
--body-quiet-color: #e0e0e0;
--body-loud-color: #ffffff;
--breadcrumbs-link-fg: #e0e0e0;
--breadcrumbs-bg: var(--primary);
--link-fg: #81d4fa;
--link-hover-color: #4ac1f7;
--link-selected-fg: #6f94c6;
--hairline-color: #272727;
--border-color: #353535;
--error-fg: #e35f5f;
--message-success-bg: #006b1b;
--message-warning-bg: #583305;
--message-error-bg: #570808;
--darkened-bg: #212121;
--selected-bg: #1b1b1b;
--selected-row: #00363a;
--close-button-bg: #333333;
--close-button-hover-bg: #666666;
}
color-scheme: light;
}
html, body {
@@ -98,8 +96,8 @@ html, body {
body {
margin: 0;
padding: 0;
font-size: 14px;
font-family: "Roboto","Lucida Grande","DejaVu Sans","Bitstream Vera Sans",Verdana,Arial,sans-serif;
font-size: 0.875rem;
font-family: var(--font-family-primary);
color: var(--body-fg);
background: var(--body-bg);
}
@@ -151,12 +149,11 @@ h1,h2,h3,h4,h5 {
h1 {
margin: 0 0 20px;
font-weight: 300;
font-size: 20px;
color: var(--body-quiet-color);
font-size: 1.25rem;
}
h2 {
font-size: 16px;
font-size: 1rem;
margin: 1em 0 .5em 0;
}
@@ -166,20 +163,21 @@ h2.subhead {
}
h3 {
font-size: 14px;
font-size: 0.875rem;
margin: .8em 0 .3em 0;
color: var(--body-quiet-color);
color: var(--body-medium-color);
font-weight: bold;
}
h4 {
font-size: 12px;
font-size: 0.75rem;
margin: 1em 0 .8em 0;
padding-bottom: 3px;
color: var(--body-medium-color);
}
h5 {
font-size: 10px;
font-size: 0.625rem;
margin: 1.5em 0 .5em 0;
color: var(--body-quiet-color);
text-transform: uppercase;
@@ -196,8 +194,8 @@ li ul {
}
li, dt, dd {
font-size: 13px;
line-height: 20px;
font-size: 0.8125rem;
line-height: 1.25rem;
}
dt {
@@ -222,8 +220,12 @@ fieldset {
border-top: 1px solid var(--hairline-color);
}
details summary {
cursor: pointer;
}
blockquote {
font-size: 11px;
font-size: 0.6875rem;
color: #777;
margin-left: 2px;
padding-left: 10px;
@@ -231,9 +233,9 @@ blockquote {
}
code, pre {
font-family: "Bitstream Vera Sans Mono", Monaco, "Courier New", Courier, monospace;
font-family: var(--font-family-monospace);
color: var(--body-quiet-color);
font-size: 12px;
font-size: 0.75rem;
overflow-x: auto;
}
@@ -255,22 +257,21 @@ hr {
border: none;
margin: 0;
padding: 0;
font-size: 1px;
line-height: 1px;
}
/* TEXT STYLES & MODIFIERS */
.small {
font-size: 11px;
font-size: 0.6875rem;
}
.mini {
font-size: 10px;
font-size: 0.625rem;
}
.help, p.help, form p.help, div.help, form div.help, div.help li {
font-size: 11px;
font-size: 0.6875rem;
color: var(--body-quiet-color);
}
@@ -300,7 +301,7 @@ p img, h1 img, h2 img, h3 img, h4 img, td img {
}
.hidden {
display: none;
display: none !important;
}
/* TABLES */
@@ -311,15 +312,15 @@ table {
}
td, th {
font-size: 13px;
line-height: 16px;
font-size: 0.8125rem;
line-height: 1rem;
border-bottom: 1px solid var(--hairline-color);
vertical-align: top;
padding: 8px;
}
th {
font-weight: 600;
font-weight: 500;
text-align: left;
}
@@ -327,7 +328,7 @@ thead th,
tfoot td {
color: var(--body-quiet-color);
padding: 5px 10px;
font-size: 11px;
font-size: 0.6875rem;
background: var(--body-bg);
border: none;
border-top: 1px solid var(--hairline-color);
@@ -340,7 +341,7 @@ tfoot td {
}
thead th.required {
color: var(--body-loud-color);
font-weight: bold;
}
tr.alt {
@@ -437,7 +438,7 @@ table thead th.sorted .sortoptions a.sortremove:after {
top: -6px;
left: 3px;
font-weight: 200;
font-size: 18px;
font-size: 1.125rem;
color: var(--body-quiet-color);
}
@@ -476,9 +477,9 @@ input, textarea, select, .form-row p, form .button {
margin: 2px 0;
padding: 2px 3px;
vertical-align: middle;
font-family: "Roboto", "Lucida Grande", Verdana, Arial, sans-serif;
font-family: var(--font-family-primary);
font-weight: normal;
font-size: 13px;
font-size: 0.8125rem;
}
.form-row div.help {
padding: 2px 3px;
@@ -488,8 +489,13 @@ textarea {
vertical-align: top;
}
input[type=text], input[type=password], input[type=email], input[type=url],
input[type=number], input[type=tel], textarea, select, .vTextField {
/*
Minifiers remove the default (text) "type" attribute from "input" HTML tags.
Add input:not([type]) to make the CSS stylesheet work the same.
*/
input:not([type]), input[type=text], input[type=password], input[type=email],
input[type=url], input[type=number], input[type=tel], textarea, select,
.vTextField {
border: 1px solid var(--border-color);
border-radius: 4px;
padding: 5px 6px;
@@ -498,14 +504,18 @@ input[type=number], input[type=tel], textarea, select, .vTextField {
background-color: var(--body-bg);
}
input[type=text]:focus, input[type=password]:focus, input[type=email]:focus,
input[type=url]:focus, input[type=number]:focus, input[type=tel]:focus,
textarea:focus, select:focus, .vTextField:focus {
/*
Minifiers remove the default (text) "type" attribute from "input" HTML tags.
Add input:not([type]) to make the CSS stylesheet work the same.
*/
input:not([type]):focus, input[type=text]:focus, input[type=password]:focus,
input[type=email]:focus, input[type=url]:focus, input[type=number]:focus,
input[type=tel]:focus, textarea:focus, select:focus, .vTextField:focus {
border-color: var(--body-quiet-color);
}
select {
height: 30px;
height: 1.875rem;
}
select[multiple] {
@@ -541,7 +551,6 @@ a.button {
}
.button.default, input[type=submit].default, .submit-row input.default {
float: right;
border: none;
font-weight: 400;
background: var(--default-button-bg);
@@ -589,15 +598,15 @@ input[type=button][disabled].default {
margin: 0;
padding: 8px;
font-weight: 400;
font-size: 13px;
font-size: 0.8125rem;
text-align: left;
background: var(--primary);
background: var(--header-bg);
color: var(--header-link-color);
}
.module caption,
.inline-group h2 {
font-size: 12px;
font-size: 0.75rem;
letter-spacing: 0.5px;
text-transform: uppercase;
}
@@ -616,12 +625,13 @@ ul.messagelist {
ul.messagelist li {
display: block;
font-weight: 400;
font-size: 13px;
font-size: 0.8125rem;
padding: 10px 10px 10px 65px;
margin: 0 0 10px 0;
background: var(--message-success-bg) url(../img/icon-yes.svg) 40px 12px no-repeat;
background-size: 16px auto;
color: var(--body-fg);
word-break: break-word;
}
ul.messagelist li.warning {
@@ -635,7 +645,7 @@ ul.messagelist li.error {
}
.errornote {
font-size: 14px;
font-size: 0.875rem;
font-weight: 700;
display: block;
padding: 10px 12px;
@@ -656,7 +666,7 @@ ul.errorlist {
}
ul.errorlist li {
font-size: 13px;
font-size: 0.8125rem;
display: block;
margin-bottom: 4px;
overflow-wrap: break-word;
@@ -697,7 +707,7 @@ td ul.errorlist + input, td ul.errorlist + select, td ul.errorlist + textarea {
}
.description {
font-size: 12px;
font-size: 0.75rem;
padding: 5px 0 0 12px;
}
@@ -726,6 +736,11 @@ div.breadcrumbs a:focus, div.breadcrumbs a:hover {
background: url(../img/icon-viewlink.svg) 0 1px no-repeat;
}
.hidelink {
padding-left: 16px;
background: url(../img/icon-hidelink.svg) 0 1px no-repeat;
}
.addlink {
padding-left: 16px;
background: url(../img/icon-addlink.svg) 0 1px no-repeat;
@@ -753,7 +768,7 @@ a.deletelink:focus, a.deletelink:hover {
/* OBJECT TOOLS */
.object-tools {
font-size: 10px;
font-size: 0.625rem;
font-weight: bold;
padding-left: 0;
float: right;
@@ -765,7 +780,7 @@ a.deletelink:focus, a.deletelink:hover {
display: block;
float: left;
margin-left: 5px;
height: 16px;
height: 1rem;
}
.object-tools a {
@@ -779,7 +794,7 @@ a.deletelink:focus, a.deletelink:hover {
background: var(--object-tools-bg);
color: var(--object-tools-fg);
font-weight: 400;
font-size: 11px;
font-size: 0.6875rem;
text-transform: uppercase;
letter-spacing: 0.5px;
}
@@ -808,14 +823,21 @@ a.deletelink:focus, a.deletelink:hover {
/* OBJECT HISTORY */
table#change-history {
#change-history table {
width: 100%;
}
table#change-history tbody th {
#change-history table tbody th {
width: 16em;
}
#change-history .paginator {
color: var(--body-quiet-color);
border-bottom: 1px solid var(--hairline-color);
background: var(--body-bg);
overflow: hidden;
}
/* PAGE STRUCTURE */
#container {
@@ -828,10 +850,6 @@ table#change-history tbody th {
height: 100%;
}
#container > div {
flex-shrink: 0;
}
#container > .main {
display: flex;
flex: 1 0 auto;
@@ -842,6 +860,20 @@ table#change-history tbody th {
max-width: 100%;
}
.skip-to-content-link {
position: absolute;
top: -999px;
margin: 5px;
padding: 5px;
background: var(--body-bg);
z-index: 1;
}
.skip-to-content-link:focus {
left: 0px;
top: 0px;
}
#content {
padding: 20px 40px;
}
@@ -862,9 +894,10 @@ table#change-history tbody th {
margin-right: -300px;
}
#footer {
clear: both;
padding: 10px;
@media (forced-colors: active) {
#content-related {
border: 1px solid;
}
}
/* COLUMN TYPES */
@@ -902,10 +935,9 @@ table#change-history tbody th {
padding: 10px 40px;
background: var(--header-bg);
color: var(--header-color);
overflow: hidden;
}
#header a:link, #header a:visited {
#header a:link, #header a:visited, #logout-form button {
color: var(--header-link-color);
}
@@ -913,25 +945,32 @@ table#change-history tbody th {
text-decoration: underline;
}
@media (forced-colors: active) {
#header {
border-bottom: 1px solid;
}
}
#branding {
float: left;
display: flex;
}
#branding h1 {
#site-name {
padding: 0;
margin: 0 20px 0 0;
margin: 0;
margin-inline-end: 20px;
font-weight: 300;
font-size: 24px;
color: var(--accent);
font-size: 1.5rem;
color: var(--header-branding-color);
}
#branding h1, #branding h1 a:link, #branding h1 a:visited {
#site-name a:link, #site-name a:visited {
color: var(--accent);
}
#branding h2 {
padding: 0 10px;
font-size: 14px;
font-size: 0.875rem;
margin: -8px 0 8px 0;
font-weight: normal;
color: var(--header-color);
@@ -941,25 +980,43 @@ table#change-history tbody th {
text-decoration: none;
}
#logout-form {
display: inline;
}
#logout-form button {
background: none;
border: 0;
cursor: pointer;
font-family: var(--font-family-primary);
}
#user-tools {
float: right;
padding: 0;
margin: 0 0 0 20px;
font-weight: 300;
font-size: 11px;
letter-spacing: 0.5px;
text-transform: uppercase;
text-align: right;
}
#user-tools a {
#user-tools, #logout-form button{
padding: 0;
font-weight: 300;
font-size: 0.6875rem;
letter-spacing: 0.5px;
text-transform: uppercase;
}
#user-tools a, #logout-form button {
border-bottom: 1px solid rgba(255, 255, 255, 0.25);
}
#user-tools a:focus, #user-tools a:hover {
#user-tools a:focus, #user-tools a:hover,
#logout-form button:active, #logout-form button:hover {
text-decoration: none;
border-bottom-color: var(--primary);
color: var(--primary);
border-bottom: 0;
}
#logout-form button:active, #logout-form button:hover {
margin-bottom: 1px;
}
/* SIDEBAR */
@@ -979,7 +1036,7 @@ table#change-history tbody th {
}
#content-related h4 {
font-size: 13px;
font-size: 0.8125rem;
}
#content-related p {
@@ -1003,7 +1060,7 @@ table#change-history tbody th {
padding: 16px;
margin-bottom: 16px;
border-bottom: 1px solid var(--hairline-color);
font-size: 18px;
font-size: 1.125rem;
color: var(--body-fg);
}
@@ -1023,8 +1080,8 @@ table#change-history tbody th {
.delete-confirmation form .cancel-link {
display: inline-block;
vertical-align: middle;
height: 15px;
line-height: 15px;
height: 0.9375rem;
line-height: 0.9375rem;
border-radius: 4px;
padding: 10px 15px;
color: var(--button-fg);
@@ -1050,3 +1107,74 @@ table#change-history tbody th {
.popup #header {
padding: 10px 20px;
}
/* PAGINATOR */
.paginator {
display: flex;
align-items: center;
gap: 4px;
font-size: 0.8125rem;
padding-top: 10px;
padding-bottom: 10px;
line-height: 22px;
margin: 0;
border-top: 1px solid var(--hairline-color);
width: 100%;
box-sizing: border-box;
}
.paginator a:link, .paginator a:visited {
padding: 2px 6px;
background: var(--button-bg);
text-decoration: none;
color: var(--button-fg);
}
.paginator a.showall {
border: none;
background: none;
color: var(--link-fg);
}
.paginator a.showall:focus, .paginator a.showall:hover {
background: none;
color: var(--link-hover-color);
}
.paginator .end {
margin-right: 6px;
}
.paginator .this-page {
padding: 2px 6px;
font-weight: bold;
font-size: 0.8125rem;
vertical-align: top;
}
.paginator a:focus, .paginator a:hover {
color: white;
background: var(--link-hover-color);
}
.paginator input {
margin-left: auto;
}
.base-svgs {
display: none;
}
.visually-hidden {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
overflow: hidden;
clip: rect(0,0,0,0);
white-space: nowrap;
border: 0;
color: var(--body-fg);
background-color: var(--body-bg);
}

View File

@@ -84,18 +84,18 @@
#toolbar form input {
border-radius: 4px;
font-size: 14px;
font-size: 0.875rem;
padding: 5px;
color: var(--body-fg);
}
#toolbar #searchbar {
height: 19px;
height: 1.1875rem;
border: 1px solid var(--border-color);
padding: 2px 5px;
margin: 0;
vertical-align: top;
font-size: 13px;
font-size: 0.8125rem;
max-width: 100%;
}
@@ -105,7 +105,7 @@
#toolbar form input[type="submit"] {
border: 1px solid var(--border-color);
font-size: 13px;
font-size: 0.8125rem;
padding: 4px 8px;
margin: 0;
vertical-align: middle;
@@ -139,8 +139,14 @@
margin: 0 0 0 30px;
}
@media (forced-colors: active) {
#changelist-filter {
border: 1px solid;
}
}
#changelist-filter h2 {
font-size: 14px;
font-size: 0.875rem;
text-transform: uppercase;
letter-spacing: 0.5px;
padding: 5px 15px;
@@ -148,12 +154,35 @@
border-bottom: none;
}
#changelist-filter h3 {
#changelist-filter h3,
#changelist-filter details summary {
font-weight: 400;
padding: 0 15px;
margin-bottom: 10px;
}
#changelist-filter details summary > * {
display: inline;
}
#changelist-filter details > summary {
list-style-type: none;
}
#changelist-filter details > summary::-webkit-details-marker {
display: none;
}
#changelist-filter details > summary::before {
content: '→';
font-weight: bold;
color: var(--link-hover-color);
}
#changelist-filter details[open] > summary::before {
content: '↓';
}
#changelist-filter ul {
margin: 5px 0;
padding: 0 15px 15px;
@@ -173,8 +202,7 @@
#changelist-filter a {
display: block;
color: var(--body-quiet-color);
text-overflow: ellipsis;
overflow-x: hidden;
word-break: break-word;
}
#changelist-filter li.selected {
@@ -193,84 +221,35 @@
color: var(--link-hover-color);
}
#changelist-filter #changelist-filter-clear a {
font-size: 13px;
padding-bottom: 10px;
#changelist-filter #changelist-filter-extra-actions {
font-size: 0.8125rem;
margin-bottom: 10px;
border-bottom: 1px solid var(--hairline-color);
}
/* DATE DRILLDOWN */
.change-list ul.toplinks {
display: block;
float: left;
padding: 0;
margin: 0;
width: 100%;
}
.change-list ul.toplinks li {
padding: 3px 6px;
.change-list .toplinks {
display: flex;
padding-bottom: 5px;
flex-wrap: wrap;
gap: 3px 17px;
font-weight: bold;
list-style-type: none;
display: inline-block;
}
.change-list ul.toplinks .date-back a {
.change-list .toplinks a {
font-size: 0.8125rem;
}
.change-list .toplinks .date-back {
color: var(--body-quiet-color);
}
.change-list ul.toplinks .date-back a:focus,
.change-list ul.toplinks .date-back a:hover {
.change-list .toplinks .date-back:focus,
.change-list .toplinks .date-back:hover {
color: var(--link-hover-color);
}
/* PAGINATOR */
.paginator {
font-size: 13px;
padding-top: 10px;
padding-bottom: 10px;
line-height: 22px;
margin: 0;
border-top: 1px solid var(--hairline-color);
width: 100%;
}
.paginator a:link, .paginator a:visited {
padding: 2px 6px;
background: var(--button-bg);
text-decoration: none;
color: var(--button-fg);
}
.paginator a.showall {
border: none;
background: none;
color: var(--link-fg);
}
.paginator a.showall:focus, .paginator a.showall:hover {
background: none;
color: var(--link-hover-color);
}
.paginator .end {
margin-right: 6px;
}
.paginator .this-page {
padding: 2px 6px;
font-weight: bold;
font-size: 13px;
vertical-align: top;
}
.paginator a:focus, .paginator a:hover {
color: white;
background: var(--link-hover-color);
}
/* ACTIONS */
.filtered .actions {
@@ -282,31 +261,40 @@
vertical-align: baseline;
}
#changelist table tbody tr.selected {
/* Once the :has() pseudo-class is supported by all browsers, the tr.selected
selector and the JS adding the class can be removed. */
#changelist tbody tr.selected {
background-color: var(--selected-row);
}
#changelist tbody tr:has(.action-select:checked) {
background-color: var(--selected-row);
}
@media (forced-colors: active) {
#changelist tbody tr.selected {
background-color: SelectedItem;
}
#changelist tbody tr:has(.action-select:checked) {
background-color: SelectedItem;
}
}
#changelist .actions {
padding: 10px;
background: var(--body-bg);
border-top: none;
border-bottom: none;
line-height: 24px;
line-height: 1.5rem;
color: var(--body-quiet-color);
width: 100%;
}
#changelist .actions.selected { /* XXX Probably unused? */
background: var(--body-bg);
border-top: 1px solid var(--body-bg);
border-bottom: 1px solid #edecd6;
}
#changelist .actions span.all,
#changelist .actions span.action-counter,
#changelist .actions span.clear,
#changelist .actions span.question {
font-size: 13px;
font-size: 0.8125rem;
margin: 0 0.5em;
}
@@ -316,11 +304,11 @@
#changelist .actions select {
vertical-align: top;
height: 24px;
height: 1.5rem;
color: var(--body-fg);
border: 1px solid var(--border-color);
border-radius: 4px;
font-size: 14px;
font-size: 0.875rem;
padding: 0 0 0 4px;
margin: 0;
margin-left: 10px;
@@ -333,17 +321,17 @@
#changelist .actions label {
display: inline-block;
vertical-align: middle;
font-size: 13px;
font-size: 0.8125rem;
}
#changelist .actions .button {
font-size: 13px;
font-size: 0.8125rem;
border: 1px solid var(--border-color);
border-radius: 4px;
background: var(--body-bg);
box-shadow: 0 -15px 20px -10px rgba(0, 0, 0, 0.15) inset;
cursor: pointer;
height: 24px;
height: 1.5rem;
line-height: 1;
padding: 4px 8px;
margin: 0;

View File

@@ -0,0 +1,130 @@
@media (prefers-color-scheme: dark) {
:root {
--primary: #264b5d;
--primary-fg: #f7f7f7;
--body-fg: #eeeeee;
--body-bg: #121212;
--body-quiet-color: #d0d0d0;
--body-medium-color: #e0e0e0;
--body-loud-color: #ffffff;
--breadcrumbs-link-fg: #e0e0e0;
--breadcrumbs-bg: var(--primary);
--link-fg: #81d4fa;
--link-hover-color: #4ac1f7;
--link-selected-fg: #6f94c6;
--hairline-color: #272727;
--border-color: #353535;
--error-fg: #e35f5f;
--message-success-bg: #006b1b;
--message-warning-bg: #583305;
--message-error-bg: #570808;
--darkened-bg: #212121;
--selected-bg: #1b1b1b;
--selected-row: #00363a;
--close-button-bg: #333333;
--close-button-hover-bg: #666666;
color-scheme: dark;
}
}
html[data-theme="dark"] {
--primary: #264b5d;
--primary-fg: #f7f7f7;
--body-fg: #eeeeee;
--body-bg: #121212;
--body-quiet-color: #d0d0d0;
--body-medium-color: #e0e0e0;
--body-loud-color: #ffffff;
--breadcrumbs-link-fg: #e0e0e0;
--breadcrumbs-bg: var(--primary);
--link-fg: #81d4fa;
--link-hover-color: #4ac1f7;
--link-selected-fg: #6f94c6;
--hairline-color: #272727;
--border-color: #353535;
--error-fg: #e35f5f;
--message-success-bg: #006b1b;
--message-warning-bg: #583305;
--message-error-bg: #570808;
--darkened-bg: #212121;
--selected-bg: #1b1b1b;
--selected-row: #00363a;
--close-button-bg: #333333;
--close-button-hover-bg: #666666;
color-scheme: dark;
}
/* THEME SWITCH */
.theme-toggle {
cursor: pointer;
border: none;
padding: 0;
background: transparent;
vertical-align: middle;
margin-inline-start: 5px;
margin-top: -1px;
}
.theme-toggle svg {
vertical-align: middle;
height: 1.5rem;
width: 1.5rem;
display: none;
}
/*
Fully hide screen reader text so we only show the one matching the current
theme.
*/
.theme-toggle .visually-hidden {
display: none;
}
html[data-theme="auto"] .theme-toggle .theme-label-when-auto {
display: block;
}
html[data-theme="dark"] .theme-toggle .theme-label-when-dark {
display: block;
}
html[data-theme="light"] .theme-toggle .theme-label-when-light {
display: block;
}
/* ICONS */
.theme-toggle svg.theme-icon-when-auto,
.theme-toggle svg.theme-icon-when-dark,
.theme-toggle svg.theme-icon-when-light {
fill: var(--header-link-color);
color: var(--header-bg);
}
html[data-theme="auto"] .theme-toggle svg.theme-icon-when-auto {
display: block;
}
html[data-theme="dark"] .theme-toggle svg.theme-icon-when-dark {
display: block;
}
html[data-theme="light"] .theme-toggle svg.theme-icon-when-light {
display: block;
}

View File

@@ -1,4 +1,7 @@
/* DASHBOARD */
.dashboard td, .dashboard th {
word-break: break-word;
}
.dashboard .module table th {
width: 100%;

View File

@@ -1,20 +0,0 @@
@font-face {
font-family: 'Roboto';
src: url('../fonts/Roboto-Bold-webfont.woff');
font-weight: 700;
font-style: normal;
}
@font-face {
font-family: 'Roboto';
src: url('../fonts/Roboto-Regular-webfont.woff');
font-weight: 400;
font-style: normal;
}
@font-face {
font-family: 'Roboto';
src: url('../fonts/Roboto-Light-webfont.woff');
font-weight: 300;
font-style: normal;
}

View File

@@ -5,7 +5,7 @@
.form-row {
overflow: hidden;
padding: 10px;
font-size: 13px;
font-size: 0.8125rem;
border-bottom: 1px solid var(--hairline-color);
}
@@ -22,17 +22,28 @@ form .form-row p {
padding-left: 0;
}
.flex-container {
display: flex;
}
.form-multiline {
flex-wrap: wrap;
}
.form-multiline > div {
padding-bottom: 10px;
}
/* FORM LABELS */
label {
font-weight: normal;
color: var(--body-quiet-color);
font-size: 13px;
font-size: 0.8125rem;
}
.required label, label.required {
font-weight: bold;
color: var(--body-fg);
}
/* RADIO BUTTONS */
@@ -64,29 +75,41 @@ form ul.inline li {
padding-right: 7px;
}
/* FIELDSETS */
fieldset .fieldset-heading,
fieldset .inline-heading,
:not(.inline-related) .collapse summary {
border: 1px solid var(--header-bg);
margin: 0;
padding: 8px;
font-weight: 400;
font-size: 0.8125rem;
background: var(--header-bg);
color: var(--header-link-color);
}
/* ALIGNED FIELDSETS */
.aligned label {
display: block;
padding: 4px 10px 0 0;
float: left;
min-width: 160px;
width: 160px;
word-wrap: break-word;
line-height: 1;
}
.aligned label:not(.vCheckboxLabel):after {
content: '';
display: inline-block;
vertical-align: middle;
height: 26px;
}
.aligned label + p, .aligned label + div.help, .aligned label + div.readonly {
.aligned label + p, .aligned .checkbox-row + div.help, .aligned label + div.readonly {
padding: 6px 0;
margin-top: 0;
margin-bottom: 0;
margin-left: 170px;
margin-left: 0;
overflow-wrap: break-word;
}
@@ -117,16 +140,17 @@ form .aligned div.radiolist {
form .aligned p.help,
form .aligned div.help {
clear: left;
margin-top: 0;
margin-left: 160px;
padding-left: 10px;
}
form .aligned label + p.help,
form .aligned label + div.help {
form .aligned p.date div.help.timezonewarning,
form .aligned p.datetime div.help.timezonewarning,
form .aligned p.time div.help.timezonewarning {
margin-left: 0;
padding-left: 0;
font-weight: normal;
}
form .aligned p.help:last-child,
@@ -145,6 +169,10 @@ form .aligned select + div.help {
padding-left: 10px;
}
form .aligned select option:checked {
background-color: var(--selected-row);
}
form .aligned ul li {
list-style: none;
}
@@ -155,11 +183,7 @@ form .aligned table p {
}
.aligned .vCheckboxLabel {
float: none;
width: auto;
display: inline-block;
vertical-align: -3px;
padding: 0 0 5px 5px;
padding: 1px 0 0 5px;
}
.aligned .vCheckboxLabel + p.help,
@@ -171,14 +195,7 @@ form .aligned table p {
width: 610px;
}
.checkbox-row p.help,
.checkbox-row div.help {
margin-left: 0;
padding-left: 0;
}
fieldset .fieldBox {
float: left;
margin-right: 20px;
}
@@ -188,15 +205,10 @@ fieldset .fieldBox {
width: 200px;
}
form .wide p,
form .wide input + p.help,
form .wide input + div.help {
margin-left: 200px;
}
form .wide p.help,
form .wide ul.errorlist,
form .wide div.help {
padding-left: 38px;
padding-left: 50px;
}
form div.help ul {
@@ -208,53 +220,36 @@ form div.help ul {
width: 450px;
}
/* COLLAPSED FIELDSETS */
/* COLLAPSIBLE FIELDSETS */
fieldset.collapsed * {
display: none;
}
fieldset.collapsed h2, fieldset.collapsed {
display: block;
}
fieldset.collapsed {
border: 1px solid var(--hairline-color);
border-radius: 4px;
overflow: hidden;
}
fieldset.collapsed h2 {
background: var(--darkened-bg);
color: var(--body-quiet-color);
}
fieldset .collapse-toggle {
color: var(--header-link-color);
}
fieldset.collapsed .collapse-toggle {
.collapse summary .fieldset-heading,
.collapse summary .inline-heading {
background: transparent;
border: none;
color: currentColor;
display: inline;
color: var(--link-fg);
margin: 0;
padding: 0;
}
/* MONOSPACE TEXTAREAS */
fieldset.monospace textarea {
font-family: "Bitstream Vera Sans Mono", Monaco, "Courier New", Courier, monospace;
font-family: var(--font-family-monospace);
}
/* SUBMIT ROW */
.submit-row {
padding: 12px 14px;
padding: 12px 14px 12px;
margin: 0 0 20px;
background: var(--darkened-bg);
border: 1px solid var(--hairline-color);
border-radius: 4px;
text-align: right;
overflow: hidden;
display: flex;
gap: 10px;
flex-wrap: wrap;
}
body.popup .submit-row {
@@ -262,32 +257,29 @@ body.popup .submit-row {
}
.submit-row input {
height: 35px;
line-height: 15px;
margin: 0 0 0 5px;
height: 2.1875rem;
line-height: 0.9375rem;
}
.submit-row input, .submit-row a {
margin: 0;
}
.submit-row input.default {
margin: 0 0 0 8px;
text-transform: uppercase;
}
.submit-row p {
margin: 0.3em;
}
.submit-row p.deletelink-box {
float: left;
margin: 0;
.submit-row a.deletelink {
margin-left: auto;
}
.submit-row a.deletelink {
display: block;
background: var(--delete-button-bg);
border-radius: 4px;
padding: 10px 15px;
height: 15px;
line-height: 15px;
padding: 0.625rem 0.9375rem;
height: 0.9375rem;
line-height: 0.9375rem;
color: var(--button-fg);
}
@@ -296,9 +288,8 @@ body.popup .submit-row {
background: var(--close-button-bg);
border-radius: 4px;
padding: 10px 15px;
height: 15px;
line-height: 15px;
margin: 0 0 0 5px;
height: 0.9375rem;
line-height: 0.9375rem;
color: var(--button-fg);
}
@@ -306,12 +297,14 @@ body.popup .submit-row {
.submit-row a.deletelink:hover,
.submit-row a.deletelink:active {
background: var(--delete-button-hover-bg);
text-decoration: none;
}
.submit-row a.closelink:focus,
.submit-row a.closelink:hover,
.submit-row a.closelink:active {
background: var(--close-button-hover-bg);
text-decoration: none;
}
/* CUSTOM FORM FIELDS */
@@ -353,10 +346,6 @@ body.popup .submit-row {
width: 2.2em;
}
.vTextField, .vUUIDField {
width: 20em;
}
.vIntegerField {
width: 5em;
}
@@ -369,6 +358,10 @@ body.popup .submit-row {
width: 5em;
}
.vTextField, .vUUIDField {
width: 20em;
}
/* INLINES */
.inline-group {
@@ -388,14 +381,16 @@ body.popup .submit-row {
position: relative;
}
.inline-related h3 {
.inline-related h4,
.inline-related:not(.tabular) .collapse summary {
margin: 0;
color: var(--body-quiet-color);
color: var(--body-medium-color);
padding: 5px;
font-size: 13px;
font-size: 0.8125rem;
background: var(--darkened-bg);
border-top: 1px solid var(--hairline-color);
border-bottom: 1px solid var(--hairline-color);
border: 1px solid var(--hairline-color);
border-left-color: var(--darkened-bg);
border-right-color: var(--darkened-bg);
}
.inline-related h3 span.delete {
@@ -404,7 +399,7 @@ body.popup .submit-row {
.inline-related h3 span.delete label {
margin-left: 2px;
font-size: 11px;
font-size: 0.6875rem;
}
.inline-related fieldset {
@@ -414,16 +409,6 @@ body.popup .submit-row {
width: 100%;
}
.inline-related fieldset.module h3 {
margin: 0;
padding: 2px 5px 3px 5px;
font-size: 11px;
text-align: left;
font-weight: bold;
background: #bcd;
color: var(--body-bg);
}
.inline-group .tabular fieldset.module {
border: none;
}
@@ -458,23 +443,12 @@ body.popup .submit-row {
height: 1.1em;
padding: 2px 9px;
overflow: hidden;
font-size: 9px;
font-size: 0.5625rem;
font-weight: bold;
color: var(--body-quiet-color);
_width: 700px;
}
.inline-group ul.tools {
padding: 0;
margin: 0;
list-style: none;
}
.inline-group ul.tools li {
display: inline;
padding: 0 5px;
}
.inline-group div.add-row,
.inline-group .tabular tr.add-row td {
color: var(--body-quiet-color);
@@ -488,12 +462,9 @@ body.popup .submit-row {
border-bottom: 1px solid var(--hairline-color);
}
.inline-group ul.tools a.add,
.inline-group div.add-row a,
.inline-group .tabular tr.add-row td a {
background: url(../img/icon-addlink.svg) 0 1px no-repeat;
padding-left: 16px;
font-size: 12px;
font-size: 0.75rem;
}
.empty-form {
@@ -511,8 +482,8 @@ body.popup .submit-row {
}
.related-lookup {
width: 16px;
height: 16px;
width: 1rem;
height: 1rem;
background-image: url(../img/search.svg);
}

View File

@@ -12,7 +12,7 @@
}
.login #header h1 {
font-size: 18px;
font-size: 1.125rem;
margin: 0;
}
@@ -21,7 +21,7 @@
}
.login #content {
padding: 20px 20px 0;
padding: 20px;
}
.login #container {

View File

@@ -16,7 +16,7 @@
border-right: 1px solid var(--hairline-color);
background-color: var(--body-bg);
cursor: pointer;
font-size: 20px;
font-size: 1.25rem;
color: var(--link-fg);
padding: 0;
}
@@ -59,8 +59,13 @@
content: '\00AB';
}
.main > #nav-sidebar {
visibility: hidden;
}
.main.shifted > #nav-sidebar {
margin-left: 0;
visibility: visible;
}
[dir="rtl"] .main.shifted > #nav-sidebar {
@@ -97,6 +102,12 @@
background: var(--selected-row);
}
@media (forced-colors: active) {
#nav-sidebar .current-model {
background-color: SelectedItem;
}
}
.main > #nav-sidebar + .content {
max-width: calc(100% - 23px);
}

View File

@@ -14,11 +14,11 @@ input[type="submit"], button {
td, th {
padding: 10px;
font-size: 14px;
font-size: 0.875rem;
}
.small {
font-size: 12px;
font-size: 0.75rem;
}
/* Layout */
@@ -28,7 +28,7 @@ input[type="submit"], button {
}
#content {
padding: 20px 30px 30px;
padding: 15px 20px 20px;
}
div.breadcrumbs {
@@ -43,9 +43,8 @@ input[type="submit"], button {
justify-content: flex-start;
}
#branding h1 {
#site-name {
margin: 0 0 8px;
font-size: 20px;
line-height: 1.2;
}
@@ -88,7 +87,7 @@ input[type="submit"], button {
}
td .changelink, td .addlink {
font-size: 13px;
font-size: 0.8125rem;
}
/* Changelist */
@@ -105,13 +104,13 @@ input[type="submit"], button {
}
#changelist-search label {
line-height: 22px;
line-height: 1.375rem;
}
#toolbar form #searchbar {
flex: 1 0 auto;
width: 0;
height: 22px;
height: 1.375rem;
margin: 0 10px 0 6px;
}
@@ -131,10 +130,6 @@ input[type="submit"], button {
padding: 15px 0;
}
#changelist .actions.selected {
border: none;
}
#changelist .actions label {
display: flex;
}
@@ -152,7 +147,7 @@ input[type="submit"], button {
#changelist .actions span.clear,
#changelist .actions span.question,
#changelist .actions span.action-counter {
font-size: 11px;
font-size: 0.6875rem;
margin: 0 10px 0 0;
}
@@ -176,9 +171,14 @@ input[type="submit"], button {
/* Forms */
label {
font-size: 14px;
font-size: 1rem;
}
/*
Minifiers remove the default (text) "type" attribute from "input" HTML
tags. Add input:not([type]) to make the CSS stylesheet work the same.
*/
.form-row input:not([type]),
.form-row input[type=text],
.form-row input[type=password],
.form-row input[type=email],
@@ -191,12 +191,12 @@ input[type="submit"], button {
box-sizing: border-box;
margin: 0;
padding: 6px 8px;
min-height: 36px;
font-size: 14px;
min-height: 2.25rem;
font-size: 1rem;
}
.form-row select {
height: 36px;
height: 2.25rem;
}
.form-row select[multiple] {
@@ -204,12 +204,6 @@ input[type="submit"], button {
min-height: 0;
}
fieldset .fieldBox {
float: none;
margin: 0 -10px;
padding: 0 10px;
}
fieldset .fieldBox + .fieldBox {
margin-top: 10px;
padding-top: 10px;
@@ -236,20 +230,16 @@ input[type="submit"], button {
margin-left: 2px;
}
/* Related widget */
.related-widget-wrapper {
float: none;
.submit-row {
padding: 8px;
}
.related-widget-wrapper-link + .selector {
max-width: calc(100% - 30px);
margin-right: 15px;
.submit-row a.deletelink {
padding: 10px 7px;
}
select + .related-widget-wrapper-link,
.related-widget-wrapper-link + .related-widget-wrapper-link {
margin-left: 10px;
.button, input[type=submit], input[type=button], .submit-row input, a.button {
padding: 7px;
}
/* Selector */
@@ -264,12 +254,8 @@ input[type="submit"], button {
align-items: center;
}
.selector .selector-filter label {
margin: 0 8px 0 0;
}
.selector .selector-filter input {
width: auto;
width: 100%;
min-height: 0;
flex: 1 1;
}
@@ -287,30 +273,7 @@ input[type="submit"], button {
margin-bottom: 5px;
}
.selector ul.selector-chooser {
width: 26px;
height: 52px;
padding: 2px 0;
margin: auto 15px;
border-radius: 20px;
transform: translateY(-10px);
}
.selector-add, .selector-remove {
width: 20px;
height: 20px;
background-size: 20px auto;
}
.selector-add {
background-position: 0 -120px;
}
.selector-remove {
background-position: 0 -80px;
}
a.selector-chooseall, a.selector-clearall {
.selector-chooseall, .selector-clearall {
align-self: center;
}
@@ -332,10 +295,7 @@ input[type="submit"], button {
}
.stacked ul.selector-chooser {
width: 52px;
height: 26px;
padding: 0 2px;
margin: 15px auto;
transform: none;
}
@@ -343,62 +303,22 @@ input[type="submit"], button {
padding: 3px;
}
.stacked .selector-add, .stacked .selector-remove {
background-size: 20px auto;
}
.stacked .selector-add {
background-position: 0 -40px;
}
.stacked .active.selector-add {
background-position: 0 -40px;
}
.active.selector-add:focus, .active.selector-add:hover {
background-position: 0 -140px;
}
.stacked .active.selector-add:focus, .stacked .active.selector-add:hover {
background-position: 0 -60px;
}
.stacked .selector-remove {
background-position: 0 0;
}
.stacked .active.selector-remove {
background-position: 0 0;
}
.active.selector-remove:focus, .active.selector-remove:hover {
background-position: 0 -100px;
}
.stacked .active.selector-remove:focus, .stacked .active.selector-remove:hover {
background-position: 0 -20px;
}
.help-tooltip, .selector .help-icon {
display: none;
}
form .form-row p.datetime {
width: 100%;
}
.datetime input {
width: 50%;
max-width: 120px;
}
.datetime span {
font-size: 13px;
font-size: 0.8125rem;
}
.datetime .timezonewarning {
display: block;
font-size: 11px;
font-size: 0.6875rem;
color: var(--body-quiet-color);
}
@@ -435,7 +355,7 @@ input[type="submit"], button {
padding: 15px 20px;
}
.login #branding h1 {
.login #site-name {
margin: 0;
}
@@ -467,14 +387,10 @@ input[type="submit"], button {
@media (max-width: 767px) {
/* Layout */
#header, #content, #footer {
#header, #content {
padding: 15px;
}
#footer:empty {
padding: 0;
}
div.breadcrumbs {
padding: 10px 15px;
}
@@ -496,7 +412,7 @@ input[type="submit"], button {
#content-related .module h2 {
padding: 10px 15px;
font-size: 16px;
font-size: 1rem;
}
/* Changelist */
@@ -557,8 +473,6 @@ input[type="submit"], button {
.aligned .form-row,
.aligned .form-row > div {
display: flex;
flex-wrap: wrap;
max-width: 100vw;
}
@@ -566,6 +480,14 @@ input[type="submit"], button {
width: calc(100vw - 30px);
}
.flex-container {
flex-flow: column;
}
.flex-container.checkbox-row {
flex-flow: row;
}
textarea {
max-width: none;
}
@@ -579,12 +501,9 @@ input[type="submit"], button {
padding-top: 15px;
}
fieldset.collapsed .form-row {
display: none;
}
.aligned label {
width: 100%;
min-width: auto;
padding: 0 0 10px;
}
@@ -599,10 +518,6 @@ input[type="submit"], button {
max-width: 100%;
}
.aligned .checkbox-row {
align-items: center;
}
.aligned .checkbox-row input {
flex: 0 1 auto;
margin: 0;
@@ -621,8 +536,7 @@ input[type="submit"], button {
}
.aligned p.file-upload {
margin-left: 0;
font-size: 13px;
font-size: 0.8125rem;
}
span.clearable-file-input {
@@ -630,7 +544,7 @@ input[type="submit"], button {
}
span.clearable-file-input label {
font-size: 13px;
font-size: 0.8125rem;
padding-bottom: 0;
}
@@ -645,7 +559,8 @@ input[type="submit"], button {
padding: 0;
}
form .aligned ul {
form .aligned ul,
form .aligned ul.errorlist {
margin-left: 0;
padding-left: 0;
}
@@ -670,6 +585,7 @@ input[type="submit"], button {
.related-widget-wrapper .selector {
order: 1;
flex: 1 0 auto;
}
.related-widget-wrapper > a {
@@ -684,23 +600,14 @@ input[type="submit"], button {
align-self: center;
}
select + .related-widget-wrapper-link,
.related-widget-wrapper-link + .related-widget-wrapper-link {
margin-left: 15px;
}
/* Selector */
.selector {
flex-direction: column;
}
.selector > * {
float: none;
gap: 10px 0;
}
.selector-available, .selector-chosen {
margin-bottom: 0;
flex: 1 1 auto;
}
@@ -709,12 +616,10 @@ input[type="submit"], button {
}
.selector ul.selector-chooser {
display: block;
float: none;
width: 52px;
height: 26px;
display: flex;
width: 60px;
height: 30px;
padding: 0 2px;
margin: 15px auto 20px;
transform: none;
}
@@ -726,16 +631,16 @@ input[type="submit"], button {
background-position: 0 0;
}
.active.selector-remove:focus, .active.selector-remove:hover {
background-position: 0 -20px;
:enabled.selector-remove:focus, :enabled.selector-remove:hover {
background-position: 0 -24px;
}
.selector-add {
background-position: 0 -40px;
background-position: 0 -48px;
}
.active.selector-add:focus, .active.selector-add:hover {
background-position: 0 -60px;
:enabled.selector-add:focus, :enabled.selector-add:hover {
background-position: 0 -72px;
}
/* Inlines */
@@ -812,28 +717,23 @@ input[type="submit"], button {
/* Submit row */
.submit-row {
padding: 10px 10px 0;
padding: 10px;
margin: 0 0 15px;
display: flex;
flex-direction: column;
gap: 8px;
}
.submit-row > * {
width: 100%;
}
.submit-row input, .submit-row input.default, .submit-row a, .submit-row a.closelink {
float: none;
margin: 0 0 10px;
.submit-row input, .submit-row input.default, .submit-row a {
text-align: center;
}
.submit-row a.closelink {
padding: 10px 0;
text-align: center;
}
.submit-row p.deletelink-box {
order: 4;
.submit-row a.deletelink {
margin: 0;
}
/* Messages */
@@ -907,7 +807,7 @@ input[type="submit"], button {
.errornote {
margin: 0 0 20px;
padding: 8px 12px;
font-size: 13px;
font-size: 0.8125rem;
}
/* Calendar and clock */
@@ -954,8 +854,8 @@ input[type="submit"], button {
.calendar-shortcuts {
padding: 10px 0;
font-size: 12px;
line-height: 12px;
font-size: 0.75rem;
line-height: 0.75rem;
}
.calendar-shortcuts a {
@@ -987,7 +887,7 @@ input[type="submit"], button {
/* History */
table#change-history tbody th, table#change-history tbody td {
font-size: 13px;
font-size: 0.8125rem;
word-break: break-word;
}
@@ -998,7 +898,7 @@ input[type="submit"], button {
/* Docs */
table.model tbody th, table.model tbody td {
font-size: 13px;
font-size: 0.8125rem;
word-break: break-word;
}
}

View File

@@ -28,23 +28,12 @@
margin-left: 0;
}
[dir="rtl"] .inline-group ul.tools a.add,
[dir="rtl"] .inline-group div.add-row a,
[dir="rtl"] .inline-group .tabular tr.add-row td a {
padding: 8px 26px 8px 10px;
background-position: calc(100% - 8px) 9px;
}
[dir="rtl"] .related-widget-wrapper-link + .selector {
margin-right: 0;
margin-left: 15px;
}
[dir="rtl"] .selector .selector-filter label {
margin-right: 0;
margin-left: 8px;
}
[dir="rtl"] .object-tools li {
float: right;
}
@@ -69,7 +58,8 @@
margin-right: 15px;
}
[dir="rtl"] .aligned ul {
[dir="rtl"] .aligned ul,
[dir="rtl"] form .aligned ul.errorlist {
margin-right: 0;
}
@@ -77,4 +67,23 @@
margin-left: 0;
margin-right: 0;
}
[dir="rtl"] .aligned .vCheckboxLabel {
padding: 1px 5px 0 0;
}
[dir="rtl"] .selector-remove {
background-position: 0 0;
}
[dir="rtl"] :enabled.selector-remove:focus, :enabled.selector-remove:hover {
background-position: 0 -24px;
}
[dir="rtl"] .selector-add {
background-position: 0 -48px;
}
[dir="rtl"] :enabled.selector-add:focus, :enabled.selector-add:hover {
background-position: 0 -72px;
}
}

View File

@@ -13,7 +13,7 @@ th {
margin-right: 1.5em;
}
.viewlink, .addlink, .changelink {
.viewlink, .addlink, .changelink, .hidelink {
padding-left: 0;
padding-right: 16px;
background-position: 100% 1px;
@@ -107,23 +107,25 @@ thead th.sorted .text {
border-left: none;
}
.paginator .end {
margin-left: 6px;
margin-right: 0;
}
.paginator input {
margin-left: 0;
margin-right: auto;
}
/* FORMS */
.aligned label {
padding: 0 0 3px 1em;
float: right;
}
.submit-row {
text-align: left
}
.submit-row p.deletelink-box {
float: right;
}
.submit-row input.default {
.submit-row a.deletelink {
margin-left: 0;
margin-right: auto;
}
.vDateField, .vTimeField {
@@ -134,13 +136,11 @@ thead th.sorted .text {
margin-left: 5px;
}
form .aligned p.help, form .aligned div.help {
clear: right;
}
form .aligned ul {
margin-right: 163px;
padding-right: 10px;
margin-left: 0;
padding-left: 0;
}
form ul.inline li {
@@ -149,12 +149,34 @@ form ul.inline li {
padding-left: 7px;
}
input[type=submit].default, .submit-row input.default {
float: left;
form .aligned p.help,
form .aligned div.help {
margin-left: 0;
margin-right: 160px;
padding-right: 10px;
}
form div.help ul,
form .aligned .checkbox-row + .help,
form .aligned p.date div.help.timezonewarning,
form .aligned p.datetime div.help.timezonewarning,
form .aligned p.time div.help.timezonewarning {
margin-right: 0;
padding-right: 0;
}
form .wide p.help,
form .wide ul.errorlist,
form .wide div.help {
padding-left: 0;
padding-right: 50px;
}
.submit-row {
text-align: right;
}
fieldset .fieldBox {
float: right;
margin-left: 20px;
margin-right: 0;
}
@@ -175,12 +197,14 @@ fieldset .fieldBox {
top: 0;
left: auto;
right: 10px;
background: url(../img/calendar-icons.svg) 0 -15px no-repeat;
}
.calendarnav-next {
top: 0;
right: auto;
left: 10px;
background: url(../img/calendar-icons.svg) 0 0 no-repeat;
}
.calendar caption, .calendarbox h2 {
@@ -195,6 +219,40 @@ fieldset .fieldBox {
text-align: right;
}
.selector-add {
background: url(../img/selector-icons.svg) 0 -96px no-repeat;
background-size: 24px auto;
}
:enabled.selector-add:focus, :enabled.selector-add:hover {
background-position: 0 -120px;
}
.selector-remove {
background: url(../img/selector-icons.svg) 0 -144px no-repeat;
background-size: 24px auto;
}
:enabled.selector-remove:focus, :enabled.selector-remove:hover {
background-position: 0 -168px;
}
.selector-chooseall {
background: url(../img/selector-icons.svg) right -128px no-repeat;
}
:enabled.selector-chooseall:focus, :enabled.selector-chooseall:hover {
background-position: 100% -144px;
}
.selector-clearall {
background: url(../img/selector-icons.svg) 0 -160px no-repeat;
}
:enabled.selector-clearall:focus, :enabled.selector-clearall:hover {
background-position: 0 -176px;
}
.inline-deletelink {
float: left;
}
@@ -225,3 +283,11 @@ form .form-row p.datetime {
margin-left: inherit;
margin-right: 2px;
}
.inline-group .tabular td.original p {
right: 0;
}
.selector .selector-chooser {
margin: 0;
}

View File

@@ -0,0 +1,19 @@
/* Hide warnings fields if usable password is selected */
form:has(#id_usable_password input[value="true"]:checked) .messagelist {
display: none;
}
/* Hide password fields if unusable password is selected */
form:has(#id_usable_password input[value="false"]:checked) .field-password1,
form:has(#id_usable_password input[value="false"]:checked) .field-password2 {
display: none;
}
/* Select appropriate submit button */
form:has(#id_usable_password input[value="true"]:checked) input[type="submit"].unset-password {
display: none;
}
form:has(#id_usable_password input[value="false"]:checked) input[type="submit"].set-password {
display: none;
}

View File

@@ -1,39 +1,67 @@
/* SELECTOR (FILTER INTERFACE) */
.selector {
width: 800px;
float: left;
display: flex;
flex: 1;
gap: 0 10px;
}
.selector select {
width: 380px;
height: 17.2em;
flex: 1 0 auto;
overflow: scroll;
width: 100%;
}
.selector-available, .selector-chosen {
float: left;
width: 380px;
text-align: center;
margin-bottom: 5px;
display: flex;
flex-direction: column;
flex: 1 1;
}
.selector-chosen select {
border-top: none;
}
.selector-available h2, .selector-chosen h2 {
.selector-available-title, .selector-chosen-title {
border: 1px solid var(--border-color);
border-radius: 4px 4px 0 0;
}
.selector-chosen h2 {
background: var(--primary);
color: var(--header-link-color);
.selector .helptext {
font-size: 0.6875rem;
}
.selector .selector-available h2 {
.selector-chosen .list-footer-display {
border: 1px solid var(--border-color);
border-top: none;
border-radius: 0 0 4px 4px;
margin: 0 0 10px;
padding: 8px;
text-align: center;
background: var(--primary);
color: var(--header-link-color);
cursor: pointer;
}
.selector-chosen .list-footer-display__clear {
color: var(--breadcrumbs-fg);
}
.selector-chosen-title {
background: var(--secondary);
color: var(--header-link-color);
padding: 8px;
}
.aligned .selector-chosen-title label {
color: var(--header-link-color);
width: 100%;
}
.selector-available-title {
background: var(--darkened-bg);
color: var(--body-quiet-color);
padding: 8px;
}
.aligned .selector-available-title label {
width: 100%;
}
.selector .selector-filter {
@@ -41,9 +69,11 @@
border-width: 0 1px;
padding: 8px;
color: var(--body-quiet-color);
font-size: 10px;
font-size: 0.625rem;
margin: 0;
text-align: left;
display: flex;
gap: 8px;
}
.selector .selector-filter label,
@@ -55,20 +85,21 @@
padding: 0;
overflow: hidden;
line-height: 1;
min-width: auto;
}
.selector .selector-available input {
width: 320px;
margin-left: 8px;
.selector-filter input {
flex-grow: 1;
}
.selector ul.selector-chooser {
float: left;
width: 22px;
align-self: center;
width: 30px;
background-color: var(--selected-bg);
border-radius: 10px;
margin: 10em 5px 0 5px;
margin: 0;
padding: 0;
transform: translateY(-17px);
}
.selector-chooser li {
@@ -82,84 +113,97 @@
margin: 0 0 10px;
border-radius: 0 0 4px 4px;
}
.selector .selector-chosen--with-filtered select {
margin: 0;
border-radius: 0;
height: 14em;
}
.selector .selector-chosen:not(.selector-chosen--with-filtered) .list-footer-display {
display: none;
}
.selector-add, .selector-remove {
width: 16px;
height: 16px;
width: 24px;
height: 24px;
display: block;
text-indent: -3000px;
overflow: hidden;
cursor: default;
opacity: 0.55;
border: none;
}
.active.selector-add, .active.selector-remove {
:enabled.selector-add, :enabled.selector-remove {
opacity: 1;
}
.active.selector-add:hover, .active.selector-remove:hover {
:enabled.selector-add:hover, :enabled.selector-remove:hover {
cursor: pointer;
}
.selector-add {
background: url(../img/selector-icons.svg) 0 -96px no-repeat;
background: url(../img/selector-icons.svg) 0 -144px no-repeat;
background-size: 24px auto;
}
.active.selector-add:focus, .active.selector-add:hover {
background-position: 0 -112px;
:enabled.selector-add:focus, :enabled.selector-add:hover {
background-position: 0 -168px;
}
.selector-remove {
background: url(../img/selector-icons.svg) 0 -64px no-repeat;
background: url(../img/selector-icons.svg) 0 -96px no-repeat;
background-size: 24px auto;
}
.active.selector-remove:focus, .active.selector-remove:hover {
background-position: 0 -80px;
:enabled.selector-remove:focus, :enabled.selector-remove:hover {
background-position: 0 -120px;
}
a.selector-chooseall, a.selector-clearall {
.selector-chooseall, .selector-clearall {
display: inline-block;
height: 16px;
text-align: left;
margin: 1px auto 3px;
margin: 0 auto;
overflow: hidden;
font-weight: bold;
line-height: 16px;
color: var(--body-quiet-color);
text-decoration: none;
opacity: 0.55;
border: none;
}
a.active.selector-chooseall:focus, a.active.selector-clearall:focus,
a.active.selector-chooseall:hover, a.active.selector-clearall:hover {
:enabled.selector-chooseall:focus, :enabled.selector-clearall:focus,
:enabled.selector-chooseall:hover, :enabled.selector-clearall:hover {
color: var(--link-fg);
}
a.active.selector-chooseall, a.active.selector-clearall {
:enabled.selector-chooseall, :enabled.selector-clearall {
opacity: 1;
}
a.active.selector-chooseall:hover, a.active.selector-clearall:hover {
:enabled.selector-chooseall:hover, :enabled.selector-clearall:hover {
cursor: pointer;
}
a.selector-chooseall {
.selector-chooseall {
padding: 0 18px 0 0;
background: url(../img/selector-icons.svg) right -160px no-repeat;
cursor: default;
}
a.active.selector-chooseall:focus, a.active.selector-chooseall:hover {
:enabled.selector-chooseall:focus, :enabled.selector-chooseall:hover {
background-position: 100% -176px;
}
a.selector-clearall {
.selector-clearall {
padding: 0 0 0 18px;
background: url(../img/selector-icons.svg) 0 -128px no-repeat;
cursor: default;
}
a.active.selector-clearall:focus, a.active.selector-clearall:hover {
:enabled.selector-clearall:focus, :enabled.selector-clearall:hover {
background-position: 0 -144px;
}
@@ -168,6 +212,7 @@ a.active.selector-clearall:focus, a.active.selector-clearall:hover {
.stacked {
float: left;
width: 490px;
display: block;
}
.stacked select {
@@ -188,11 +233,13 @@ a.active.selector-clearall:focus, a.active.selector-clearall:hover {
}
.stacked ul.selector-chooser {
height: 22px;
width: 50px;
display: flex;
height: 30px;
width: 64px;
margin: 0 0 10px 40%;
background-color: #eee;
border-radius: 10px;
transform: none;
}
.stacked .selector-chooser li {
@@ -205,32 +252,34 @@ a.active.selector-clearall:focus, a.active.selector-clearall:hover {
}
.stacked .selector-add {
background: url(../img/selector-icons.svg) 0 -32px no-repeat;
background: url(../img/selector-icons.svg) 0 -48px no-repeat;
background-size: 24px auto;
cursor: default;
}
.stacked .active.selector-add {
background-position: 0 -32px;
.stacked :enabled.selector-add {
background-position: 0 -48px;
cursor: pointer;
}
.stacked .active.selector-add:focus, .stacked .active.selector-add:hover {
background-position: 0 -48px;
.stacked :enabled.selector-add:focus, .stacked :enabled.selector-add:hover {
background-position: 0 -72px;
cursor: pointer;
}
.stacked .selector-remove {
background: url(../img/selector-icons.svg) 0 0 no-repeat;
background-size: 24px auto;
cursor: default;
}
.stacked .active.selector-remove {
.stacked :enabled.selector-remove {
background-position: 0 0px;
cursor: pointer;
}
.stacked .active.selector-remove:focus, .stacked .active.selector-remove:hover {
background-position: 0 -16px;
.stacked :enabled.selector-remove:focus, .stacked :enabled.selector-remove:hover {
background-position: 0 -24px;
cursor: pointer;
}
@@ -250,8 +299,8 @@ a.active.selector-clearall:focus, a.active.selector-clearall:hover {
.selector .search-label-icon {
background: url(../img/search.svg) 0 0 no-repeat;
display: inline-block;
height: 18px;
width: 18px;
height: 1.125rem;
width: 1.125rem;
}
/* DATE AND TIME */
@@ -267,7 +316,7 @@ p.datetime {
.datetime span {
white-space: nowrap;
font-weight: normal;
font-size: 11px;
font-size: 0.6875rem;
color: var(--body-quiet-color);
}
@@ -277,7 +326,7 @@ p.datetime {
}
table p.datetime {
font-size: 11px;
font-size: 0.6875rem;
margin-left: 0;
padding-left: 0;
}
@@ -286,32 +335,34 @@ table p.datetime {
position: relative;
display: inline-block;
vertical-align: middle;
height: 16px;
width: 16px;
height: 24px;
width: 24px;
overflow: hidden;
}
.datetimeshortcuts .clock-icon {
background: url(../img/icon-clock.svg) 0 0 no-repeat;
background-size: 24px auto;
}
.datetimeshortcuts a:focus .clock-icon,
.datetimeshortcuts a:hover .clock-icon {
background-position: 0 -16px;
background-position: 0 -24px;
}
.datetimeshortcuts .date-icon {
background: url(../img/icon-calendar.svg) 0 0 no-repeat;
background-size: 24px auto;
top: -1px;
}
.datetimeshortcuts a:focus .date-icon,
.datetimeshortcuts a:hover .date-icon {
background-position: 0 -16px;
background-position: 0 -24px;
}
.timezonewarning {
font-size: 11px;
font-size: 0.6875rem;
color: var(--body-quiet-color);
}
@@ -322,7 +373,7 @@ p.url {
margin: 0;
padding: 0;
color: var(--body-quiet-color);
font-size: 11px;
font-size: 0.6875rem;
font-weight: bold;
}
@@ -337,14 +388,10 @@ p.file-upload {
margin: 0;
padding: 0;
color: var(--body-quiet-color);
font-size: 11px;
font-size: 0.6875rem;
font-weight: bold;
}
.aligned p.file-upload {
margin-left: 170px;
}
.file-upload a {
font-weight: normal;
}
@@ -355,7 +402,7 @@ p.file-upload {
span.clearable-file-input label {
color: var(--body-fg);
font-size: 11px;
font-size: 0.6875rem;
display: inline;
float: none;
}
@@ -364,7 +411,7 @@ span.clearable-file-input label {
.calendarbox, .clockbox {
margin: 5px auto;
font-size: 12px;
font-size: 0.75rem;
width: 19em;
text-align: center;
background: var(--body-bg);
@@ -398,7 +445,7 @@ span.clearable-file-input label {
text-align: center;
border-top: none;
font-weight: 700;
font-size: 12px;
font-size: 0.75rem;
color: #333;
background: var(--accent);
}
@@ -408,14 +455,14 @@ span.clearable-file-input label {
background: var(--darkened-bg);
border-bottom: 1px solid var(--border-color);
font-weight: 400;
font-size: 12px;
font-size: 0.75rem;
text-align: center;
color: var(--body-quiet-color);
}
.calendar td {
font-weight: 400;
font-size: 12px;
font-size: 0.75rem;
text-align: center;
padding: 0;
border-top: 1px solid var(--hairline-color);
@@ -423,7 +470,7 @@ span.clearable-file-input label {
}
.calendar td.selected a {
background: var(--primary);
background: var(--secondary);
color: var(--button-fg);
}
@@ -455,7 +502,7 @@ span.clearable-file-input label {
}
.calendarnav {
font-size: 10px;
font-size: 0.625rem;
text-align: center;
color: #ccc;
margin: 0;
@@ -470,8 +517,8 @@ span.clearable-file-input label {
.calendar-shortcuts {
background: var(--body-bg);
color: var(--body-quiet-color);
font-size: 11px;
line-height: 11px;
font-size: 0.6875rem;
line-height: 0.6875rem;
border-top: 1px solid var(--hairline-color);
padding: 8px 0;
}
@@ -491,36 +538,26 @@ span.clearable-file-input label {
background: url(../img/calendar-icons.svg) 0 0 no-repeat;
}
.calendarbox .calendarnav-previous:focus,
.calendarbox .calendarnav-previous:hover {
background-position: 0 -15px;
}
.calendarnav-next {
right: 10px;
background: url(../img/calendar-icons.svg) 0 -30px no-repeat;
}
.calendarbox .calendarnav-next:focus,
.calendarbox .calendarnav-next:hover {
background-position: 0 -45px;
background: url(../img/calendar-icons.svg) 0 -15px no-repeat;
}
.calendar-cancel {
margin: 0;
padding: 4px 0;
font-size: 12px;
background: #eee;
font-size: 0.75rem;
background: var(--close-button-bg);
border-top: 1px solid var(--border-color);
color: var(--body-fg);
color: var(--button-fg);
}
.calendar-cancel:focus, .calendar-cancel:hover {
background: #ddd;
background: var(--close-button-hover-bg);
}
.calendar-cancel a {
color: black;
color: var(--button-fg);
display: block;
}
@@ -540,9 +577,10 @@ ul.timelist, .timelist li {
float: right;
text-indent: -9999px;
background: url(../img/inline-delete.svg) 0 0 no-repeat;
width: 16px;
height: 16px;
width: 1.5rem;
height: 1.5rem;
border: 0px none;
margin-bottom: .25rem;
}
.inline-deletelink:focus, .inline-deletelink:hover {
@@ -551,24 +589,25 @@ ul.timelist, .timelist li {
/* RELATED WIDGET WRAPPER */
.related-widget-wrapper {
float: left; /* display properly in form rows with multiple fields */
overflow: hidden; /* clear floated contents */
display: flex;
gap: 0 10px;
flex-grow: 1;
flex-wrap: wrap;
margin-bottom: 5px;
}
.related-widget-wrapper-link {
opacity: 0.3;
opacity: .6;
filter: grayscale(1);
}
.related-widget-wrapper-link:link {
opacity: .8;
}
.related-widget-wrapper-link:link:focus,
.related-widget-wrapper-link:link:hover {
opacity: 1;
filter: grayscale(0);
}
select + .related-widget-wrapper-link,
.related-widget-wrapper-link + .related-widget-wrapper-link {
margin-left: 7px;
/* GIS MAPS */
.dj_map {
width: 600px;
height: 400px;
}

View File

@@ -1,202 +0,0 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@@ -1,3 +0,0 @@
Roboto webfont source: https://www.google.com/fonts/specimen/Roboto
WOFF files extracted using https://github.com/majodev/google-webfonts-helper
Weights used in this project: Light (300), Regular (400), Bold (700)

View File

@@ -1,4 +1,4 @@
All icons are taken from Font Awesome (http://fontawesome.io/) project.
All icons are taken from Font Awesome (https://fontawesome.com/) project.
The Font Awesome font is licensed under the SIL OFL 1.1:
- https://scripts.sil.org/OFL

View File

@@ -1,14 +1,63 @@
<svg width="15" height="60" viewBox="0 0 1792 7168" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<g id="previous">
<path d="M1037 1395l102-102q19-19 19-45t-19-45l-307-307 307-307q19-19 19-45t-19-45l-102-102q-19-19-45-19t-45 19l-454 454q-19 19-19 45t19 45l454 454q19 19 45 19t45-19zm627-499q0 209-103 385.5t-279.5 279.5-385.5 103-385.5-103-279.5-279.5-103-385.5 103-385.5 279.5-279.5 385.5-103 385.5 103 279.5 279.5 103 385.5z"/>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="15"
height="30"
viewBox="0 0 1792 3584"
version="1.1"
id="svg5"
sodipodi:docname="calendar-icons.svg"
inkscape:version="1.3.2 (091e20ef0f, 2023-11-25, custom)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview5"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
showgrid="false"
inkscape:zoom="13.3"
inkscape:cx="15.526316"
inkscape:cy="20.977444"
inkscape:window-width="1920"
inkscape:window-height="1011"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg5" />
<defs
id="defs2">
<g
id="previous">
<path
d="m 1037,1395 102,-102 q 19,-19 19,-45 0,-26 -19,-45 L 832,896 1139,589 q 19,-19 19,-45 0,-26 -19,-45 L 1037,397 q -19,-19 -45,-19 -26,0 -45,19 L 493,851 q -19,19 -19,45 0,26 19,45 l 454,454 q 19,19 45,19 26,0 45,-19 z m 627,-499 q 0,209 -103,385.5 Q 1458,1458 1281.5,1561 1105,1664 896,1664 687,1664 510.5,1561 334,1458 231,1281.5 128,1105 128,896 128,687 231,510.5 334,334 510.5,231 687,128 896,128 1105,128 1281.5,231 1458,334 1561,510.5 1664,687 1664,896 Z"
id="path1" />
</g>
<g id="next">
<path d="M845 1395l454-454q19-19 19-45t-19-45l-454-454q-19-19-45-19t-45 19l-102 102q-19 19-19 45t19 45l307 307-307 307q-19 19-19 45t19 45l102 102q19 19 45 19t45-19zm819-499q0 209-103 385.5t-279.5 279.5-385.5 103-385.5-103-279.5-279.5-103-385.5 103-385.5 279.5-279.5 385.5-103 385.5 103 279.5 279.5 103 385.5z"/>
<g
id="next">
<path
d="m 845,1395 454,-454 q 19,-19 19,-45 0,-26 -19,-45 L 845,397 q -19,-19 -45,-19 -26,0 -45,19 L 653,499 q -19,19 -19,45 0,26 19,45 l 307,307 -307,307 q -19,19 -19,45 0,26 19,45 l 102,102 q 19,19 45,19 26,0 45,-19 z m 819,-499 q 0,209 -103,385.5 Q 1458,1458 1281.5,1561 1105,1664 896,1664 687,1664 510.5,1561 334,1458 231,1281.5 128,1105 128,896 128,687 231,510.5 334,334 510.5,231 687,128 896,128 1105,128 1281.5,231 1458,334 1561,510.5 1664,687 1664,896 Z"
id="path2" />
</g>
</defs>
<use xlink:href="#previous" x="0" y="0" fill="#333333" />
<use xlink:href="#previous" x="0" y="1792" fill="#000000" />
<use xlink:href="#next" x="0" y="3584" fill="#333333" />
<use xlink:href="#next" x="0" y="5376" fill="#000000" />
<use
xlink:href="#next"
x="0"
y="5376"
fill="#000000"
id="use5"
transform="translate(0,-3584)" />
<use
xlink:href="#previous"
x="0"
y="0"
fill="#333333"
id="use2"
style="fill:#000000;fill-opacity:1" />
</svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

@@ -1,3 +1,3 @@
<svg width="13" height="13" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg">
<path fill="#70bf2b" d="M1600 796v192q0 40-28 68t-68 28h-416v416q0 40-28 68t-68 28h-192q-40 0-68-28t-28-68v-416h-416q-40 0-68-28t-28-68v-192q0-40 28-68t68-28h416v-416q0-40 28-68t68-28h192q40 0 68 28t28 68v416h416q40 0 68 28t28 68z"/>
<path fill="#5fa225" d="M1600 796v192q0 40-28 68t-68 28h-416v416q0 40-28 68t-68 28h-192q-40 0-68-28t-28-68v-416h-416q-40 0-68-28t-28-68v-192q0-40 28-68t68-28h416v-416q0-40 28-68t68-28h192q40 0 68 28t28 68v416h416q40 0 68 28t28 68z"/>
</svg>

Before

Width:  |  Height:  |  Size: 331 B

After

Width:  |  Height:  |  Size: 331 B

View File

@@ -1,3 +1,3 @@
<svg width="13" height="13" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg">
<path fill="#efb80b" d="M491 1536l91-91-235-235-91 91v107h128v128h107zm523-928q0-22-22-22-10 0-17 7l-542 542q-7 7-7 17 0 22 22 22 10 0 17-7l542-542q7-7 7-17zm-54-192l416 416-832 832h-416v-416zm683 96q0 53-37 90l-166 166-416-416 166-165q36-38 90-38 53 0 91 38l235 234q37 39 37 91z"/>
<path fill="#b48c08" d="M491 1536l91-91-235-235-91 91v107h128v128h107zm523-928q0-22-22-22-10 0-17 7l-542 542q-7 7-7 17 0 22 22 22 10 0 17-7l542-542q7-7 7-17zm-54-192l416 416-832 832h-416v-416zm683 96q0 53-37 90l-166 166-416-416 166-165q36-38 90-38 53 0 91 38l235 234q37 39 37 91z"/>
</svg>

Before

Width:  |  Height:  |  Size: 380 B

After

Width:  |  Height:  |  Size: 380 B

View File

@@ -0,0 +1,3 @@
<svg width="13" height="13" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg">
<path fill="#2b70bf" d="m555 1335 78-141q-87-63-136-159t-49-203q0-121 61-225-229 117-381 353 167 258 427 375zm389-759q0-20-14-34t-34-14q-125 0-214.5 89.5T592 832q0 20 14 34t34 14 34-14 14-34q0-86 61-147t147-61q20 0 34-14t14-34zm363-191q0 7-1 9-105 188-315 566t-316 567l-49 89q-10 16-28 16-12 0-134-70-16-10-16-28 0-12 44-87-143-65-263.5-173T20 1029Q0 998 0 960t20-69q153-235 380-371t496-136q89 0 180 17l54-97q10-16 28-16 5 0 18 6t31 15.5 33 18.5 31.5 18.5T1291 358q16 10 16 27zm37 447q0 139-79 253.5T1056 1250l280-502q8 45 8 84zm448 128q0 35-20 69-39 64-109 145-150 172-347.5 267T896 1536l74-132q212-18 392.5-137T1664 960q-115-179-282-294l63-112q95 64 182.5 153T1772 891q20 34 20 69z"/>
</svg>

After

Width:  |  Height:  |  Size: 784 B

View File

@@ -1,3 +1,3 @@
<svg width="16" height="16" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg">
<svg viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg">
<path fill="#999999" d="M1277 1122q0-26-19-45l-181-181 181-181q19-19 19-45 0-27-19-46l-90-90q-19-19-46-19-26 0-45 19l-181 181-181-181q-19-19-45-19-27 0-46 19l-90 90q-19 19-19 46 0 26 19 45l181 181-181 181q-19 19-19 45 0 27 19 46l90 90q19 19 46 19 26 0 45-19l181-181 181 181q19 19 45 19 27 0 46-19l90-90q19-19 19-46zm387-226q0 209-103 385.5t-279.5 279.5-385.5 103-385.5-103-279.5-279.5-103-385.5 103-385.5 279.5-279.5 385.5-103 385.5 103 279.5 279.5 103 385.5z"/>
</svg>

Before

Width:  |  Height:  |  Size: 560 B

After

Width:  |  Height:  |  Size: 537 B

View File

@@ -41,6 +41,10 @@
}
SelectBox.redisplay(id);
},
get_hidden_node_count(id) {
const cache = SelectBox.cache[id] || [];
return cache.filter(node => node.displayed === 0).length;
},
delete_from_cache: function(id, value) {
let delete_index = null;
const cache = SelectBox.cache[id];

View File

@@ -1,4 +1,4 @@
/*global SelectBox, gettext, interpolate, quickElement, SelectFilter*/
/*global SelectBox, gettext, ngettext, interpolate, quickElement, SelectFilter*/
/*
SelectFilter2 - Turns a multiple-select box into a filter interface.
@@ -15,6 +15,7 @@ Requires core.js and SelectBox.js.
const from_box = document.getElementById(field_id);
from_box.id += '_from'; // change its ID
from_box.className = 'filtered';
from_box.setAttribute('aria-labelledby', field_id + '_from_title');
for (const p of from_box.parentNode.getElementsByTagName('p')) {
if (p.classList.contains("info")) {
@@ -30,23 +31,23 @@ Requires core.js and SelectBox.js.
// <div class="selector"> or <div class="selector stacked">
const selector_div = quickElement('div', from_box.parentNode);
// Make sure the selector div is at the beginning so that the
// add link would be displayed to the right of the widget.
from_box.parentNode.prepend(selector_div);
selector_div.className = is_stacked ? 'selector stacked' : 'selector';
// <div class="selector-available">
const selector_available = quickElement('div', selector_div);
selector_available.className = 'selector-available';
const title_available = quickElement('h2', selector_available, interpolate(gettext('Available %s') + ' ', [field_name]));
const selector_available_title = quickElement('div', selector_available);
selector_available_title.id = field_id + '_from_title';
selector_available_title.className = 'selector-available-title';
quickElement('label', selector_available_title, interpolate(gettext('Available %s') + ' ', [field_name]), 'for', field_id + '_from');
quickElement(
'span', title_available, '',
'class', 'help help-tooltip help-icon',
'title', interpolate(
gettext(
'This is the list of available %s. You may choose some by ' +
'selecting them in the box below and then clicking the ' +
'"Choose" arrow between the two boxes.'
),
[field_name]
)
'p',
selector_available_title,
interpolate(gettext('Choose %s by selecting them and then select the "Choose" arrow button.'), [field_name]),
'class', 'helptext'
);
const filter_p = quickElement('p', selector_available, '', 'id', field_id + '_filter');
@@ -57,7 +58,7 @@ Requires core.js and SelectBox.js.
quickElement(
'span', search_filter_label, '',
'class', 'help-tooltip search-label-icon',
'title', interpolate(gettext("Type into this box to filter down the list of available %s."), [field_name])
'aria-label', interpolate(gettext("Type into this box to filter down the list of available %s."), [field_name])
);
filter_p.appendChild(document.createTextNode(' '));
@@ -66,69 +67,135 @@ Requires core.js and SelectBox.js.
filter_input.id = field_id + '_input';
selector_available.appendChild(from_box);
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');
choose_all.className = 'selector-chooseall';
const choose_all = quickElement(
'button',
selector_available,
interpolate(gettext('Choose all %s'), [field_name]),
'id', field_id + '_add_all',
'class', 'selector-chooseall',
'type', 'button'
);
// <ul class="selector-chooser">
const selector_chooser = quickElement('ul', selector_div);
selector_chooser.className = 'selector-chooser';
const add_link = quickElement('a', quickElement('li', selector_chooser), gettext('Choose'), 'title', gettext('Choose'), 'href', '#', 'id', field_id + '_add_link');
add_link.className = 'selector-add';
const remove_link = quickElement('a', quickElement('li', selector_chooser), gettext('Remove'), 'title', gettext('Remove'), 'href', '#', 'id', field_id + '_remove_link');
remove_link.className = 'selector-remove';
// <div class="selector-chosen">
const selector_chosen = quickElement('div', selector_div);
selector_chosen.className = 'selector-chosen';
const title_chosen = quickElement('h2', selector_chosen, interpolate(gettext('Chosen %s') + ' ', [field_name]));
quickElement(
'span', title_chosen, '',
'class', 'help help-tooltip help-icon',
'title', interpolate(
gettext(
'This is the list of chosen %s. You may remove some by ' +
'selecting them in the box below and then clicking the ' +
'"Remove" arrow between the two boxes.'
),
[field_name]
)
const add_button = quickElement(
'button',
quickElement('li', selector_chooser),
interpolate(gettext('Choose selected %s'), [field_name]),
'id', field_id + '_add',
'class', 'selector-add',
'type', 'button'
);
const remove_button = quickElement(
'button',
quickElement('li', selector_chooser),
interpolate(gettext('Remove selected %s'), [field_name]),
'id', field_id + '_remove',
'class', 'selector-remove',
'type', 'button'
);
const to_box = quickElement('select', selector_chosen, '', 'id', field_id + '_to', 'multiple', '', 'size', from_box.size, 'name', from_box.name);
to_box.className = 'filtered';
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');
clear_all.className = 'selector-clearall';
// <div class="selector-chosen">
const selector_chosen = quickElement('div', selector_div, '', 'id', field_id + '_selector_chosen');
selector_chosen.className = 'selector-chosen';
const selector_chosen_title = quickElement('div', selector_chosen);
selector_chosen_title.className = 'selector-chosen-title';
selector_chosen_title.id = field_id + '_to_title';
quickElement('label', selector_chosen_title, interpolate(gettext('Chosen %s') + ' ', [field_name]), 'for', field_id + '_to');
quickElement(
'p',
selector_chosen_title,
interpolate(gettext('Remove %s by selecting them and then select the "Remove" arrow button.'), [field_name]),
'class', 'helptext'
);
const filter_selected_p = quickElement('p', selector_chosen, '', 'id', field_id + '_filter_selected');
filter_selected_p.className = 'selector-filter';
const search_filter_selected_label = quickElement('label', filter_selected_p, '', 'for', field_id + '_selected_input');
quickElement(
'span', search_filter_selected_label, '',
'class', 'help-tooltip search-label-icon',
'aria-label', interpolate(gettext("Type into this box to filter down the list of selected %s."), [field_name])
);
filter_selected_p.appendChild(document.createTextNode(' '));
const filter_selected_input = quickElement('input', filter_selected_p, '', 'type', 'text', 'placeholder', gettext("Filter"));
filter_selected_input.id = field_id + '_selected_input';
quickElement(
'select',
selector_chosen,
'',
'id', field_id + '_to',
'multiple', '',
'size', from_box.size,
'name', from_box.name,
'aria-labelledby', field_id + '_to_title',
'class', 'filtered'
);
const warning_footer = quickElement('div', selector_chosen, '', 'class', 'list-footer-display');
quickElement('span', warning_footer, '', 'id', field_id + '_list-footer-display-text');
quickElement('span', warning_footer, ' ' + gettext('(click to clear)'), 'class', 'list-footer-display__clear');
const clear_all = quickElement(
'button',
selector_chosen,
interpolate(gettext('Remove all %s'), [field_name]),
'id', field_id + '_remove_all',
'class', 'selector-clearall',
'type', 'button'
);
from_box.name = from_box.name + '_old';
// Set up the JavaScript event handlers for the select box filter interface
const move_selection = function(e, elem, move_func, from, to) {
if (elem.classList.contains('active')) {
if (!elem.hasAttribute('disabled')) {
move_func(from, to);
SelectFilter.refresh_icons(field_id);
SelectFilter.refresh_filtered_selects(field_id);
SelectFilter.refresh_filtered_warning(field_id);
}
e.preventDefault();
};
choose_all.addEventListener('click', function(e) {
move_selection(e, this, SelectBox.move_all, field_id + '_from', field_id + '_to');
});
add_link.addEventListener('click', function(e) {
add_button.addEventListener('click', function(e) {
move_selection(e, this, SelectBox.move, field_id + '_from', field_id + '_to');
});
remove_link.addEventListener('click', function(e) {
remove_button.addEventListener('click', function(e) {
move_selection(e, this, SelectBox.move, field_id + '_to', field_id + '_from');
});
clear_all.addEventListener('click', function(e) {
move_selection(e, this, SelectBox.move_all, field_id + '_to', field_id + '_from');
});
warning_footer.addEventListener('click', function(e) {
filter_selected_input.value = '';
SelectBox.filter(field_id + '_to', '');
SelectFilter.refresh_filtered_warning(field_id);
SelectFilter.refresh_icons(field_id);
});
filter_input.addEventListener('keypress', function(e) {
SelectFilter.filter_key_press(e, field_id);
SelectFilter.filter_key_press(e, field_id, '_from', '_to');
});
filter_input.addEventListener('keyup', function(e) {
SelectFilter.filter_key_up(e, field_id);
SelectFilter.filter_key_up(e, field_id, '_from');
});
filter_input.addEventListener('keydown', function(e) {
SelectFilter.filter_key_down(e, field_id);
SelectFilter.filter_key_down(e, field_id, '_from', '_to');
});
filter_selected_input.addEventListener('keypress', function(e) {
SelectFilter.filter_key_press(e, field_id, '_to', '_from');
});
filter_selected_input.addEventListener('keyup', function(e) {
SelectFilter.filter_key_up(e, field_id, '_to', '_selected_input');
});
filter_selected_input.addEventListener('keydown', function(e) {
SelectFilter.filter_key_down(e, field_id, '_to', '_from');
});
selector_div.addEventListener('change', function(e) {
if (e.target.tagName === 'SELECT') {
@@ -146,6 +213,7 @@ Requires core.js and SelectBox.js.
}
});
from_box.closest('form').addEventListener('submit', function() {
SelectBox.filter(field_id + '_to', '');
SelectBox.select_all(field_id + '_to');
});
SelectBox.init(field_id + '_from');
@@ -153,24 +221,6 @@ Requires core.js and SelectBox.js.
// Move selected from_box options to to_box
SelectBox.move(field_id + '_from', field_id + '_to');
if (!is_stacked) {
// In horizontal mode, give the same height to the two boxes.
const j_from_box = document.getElementById(field_id + '_from');
const j_to_box = document.getElementById(field_id + '_to');
let height = filter_p.offsetHeight + j_from_box.offsetHeight;
const j_to_box_style = window.getComputedStyle(j_to_box);
if (j_to_box_style.getPropertyValue('box-sizing') === 'border-box') {
// Add the padding and border to the final height.
height += parseInt(j_to_box_style.getPropertyValue('padding-top'), 10)
+ parseInt(j_to_box_style.getPropertyValue('padding-bottom'), 10)
+ parseInt(j_to_box_style.getPropertyValue('border-top-width'), 10)
+ parseInt(j_to_box_style.getPropertyValue('border-bottom-width'), 10);
}
j_to_box.style.height = height + 'px';
}
// Initial icon refresh
SelectFilter.refresh_icons(field_id);
},
@@ -181,48 +231,73 @@ Requires core.js and SelectBox.js.
field.required = false;
return any_selected;
},
refresh_filtered_warning: function(field_id) {
const count = SelectBox.get_hidden_node_count(field_id + '_to');
const selector = document.getElementById(field_id + '_selector_chosen');
const warning = document.getElementById(field_id + '_list-footer-display-text');
selector.className = selector.className.replace('selector-chosen--with-filtered', '');
warning.textContent = interpolate(ngettext(
'%s selected option not visible',
'%s selected options not visible',
count
), [count]);
if(count > 0) {
selector.className += ' selector-chosen--with-filtered';
}
},
refresh_filtered_selects: function(field_id) {
SelectBox.filter(field_id + '_from', document.getElementById(field_id + "_input").value);
SelectBox.filter(field_id + '_to', document.getElementById(field_id + "_selected_input").value);
},
refresh_icons: function(field_id) {
const from = document.getElementById(field_id + '_from');
const to = document.getElementById(field_id + '_to');
// Active if at least one item is selected
document.getElementById(field_id + '_add_link').classList.toggle('active', SelectFilter.any_selected(from));
document.getElementById(field_id + '_remove_link').classList.toggle('active', SelectFilter.any_selected(to));
// Active if the corresponding box isn't empty
document.getElementById(field_id + '_add_all_link').classList.toggle('active', from.querySelector('option'));
document.getElementById(field_id + '_remove_all_link').classList.toggle('active', to.querySelector('option'));
// Disabled if no items are selected.
document.getElementById(field_id + '_add').disabled = !SelectFilter.any_selected(from);
document.getElementById(field_id + '_remove').disabled = !SelectFilter.any_selected(to);
// Disabled if the corresponding box is empty.
document.getElementById(field_id + '_add_all').disabled = !from.querySelector('option');
document.getElementById(field_id + '_remove_all').disabled = !to.querySelector('option');
},
filter_key_press: function(event, field_id) {
const from = document.getElementById(field_id + '_from');
filter_key_press: function(event, field_id, source, target) {
const source_box = document.getElementById(field_id + source);
// don't submit form if user pressed Enter
if ((event.which && event.which === 13) || (event.keyCode && event.keyCode === 13)) {
from.selectedIndex = 0;
SelectBox.move(field_id + '_from', field_id + '_to');
from.selectedIndex = 0;
source_box.selectedIndex = 0;
SelectBox.move(field_id + source, field_id + target);
source_box.selectedIndex = 0;
event.preventDefault();
}
},
filter_key_up: function(event, field_id) {
const from = document.getElementById(field_id + '_from');
const temp = from.selectedIndex;
SelectBox.filter(field_id + '_from', document.getElementById(field_id + '_input').value);
from.selectedIndex = temp;
filter_key_up: function(event, field_id, source, filter_input) {
const input = filter_input || '_input';
const source_box = document.getElementById(field_id + source);
const temp = source_box.selectedIndex;
SelectBox.filter(field_id + source, document.getElementById(field_id + input).value);
source_box.selectedIndex = temp;
SelectFilter.refresh_filtered_warning(field_id);
SelectFilter.refresh_icons(field_id);
},
filter_key_down: function(event, field_id) {
const from = document.getElementById(field_id + '_from');
filter_key_down: function(event, field_id, source, target) {
const source_box = document.getElementById(field_id + source);
// right key (39) or left key (37)
const direction = source === '_from' ? 39 : 37;
// right arrow -- move across
if ((event.which && event.which === 39) || (event.keyCode && event.keyCode === 39)) {
const old_index = from.selectedIndex;
SelectBox.move(field_id + '_from', field_id + '_to');
from.selectedIndex = (old_index === from.length) ? from.length - 1 : old_index;
if ((event.which && event.which === direction) || (event.keyCode && event.keyCode === direction)) {
const old_index = source_box.selectedIndex;
SelectBox.move(field_id + source, field_id + target);
SelectFilter.refresh_filtered_selects(field_id);
SelectFilter.refresh_filtered_warning(field_id);
source_box.selectedIndex = (old_index === source_box.length) ? source_box.length - 1 : old_index;
return;
}
// down arrow -- wrap around
if ((event.which && event.which === 40) || (event.keyCode && event.keyCode === 40)) {
from.selectedIndex = (from.length === from.selectedIndex + 1) ? 0 : from.selectedIndex + 1;
source_box.selectedIndex = (source_box.length === source_box.selectedIndex + 1) ? 0 : source_box.selectedIndex + 1;
}
// up arrow -- wrap around
if ((event.which && event.which === 38) || (event.keyCode && event.keyCode === 38)) {
from.selectedIndex = (from.selectedIndex === 0) ? from.length - 1 : from.selectedIndex - 1;
source_box.selectedIndex = (source_box.selectedIndex === 0) ? source_box.length - 1 : source_box.selectedIndex - 1;
}
}
};

View File

@@ -1,4 +1,4 @@
/*global gettext, interpolate, ngettext*/
/*global gettext, interpolate, ngettext, Actions*/
'use strict';
{
function show(selector) {
@@ -179,6 +179,9 @@
}
});
}
// Sync counter when navigating to the page, such as through the back
// button.
window.addEventListener('pageshow', (event) => updateCounter(actionCheckboxes, options));
};
// Call function fn when the DOM is loaded and ready. If it is already

View File

@@ -90,10 +90,9 @@
}
message = interpolate(message, [timezoneOffset]);
const warning = document.createElement('span');
warning.className = warningClass;
const warning = document.createElement('div');
warning.classList.add('help', warningClass);
warning.textContent = message;
inp.parentNode.appendChild(document.createElement('br'));
inp.parentNode.appendChild(warning);
},
// Add clock widget to a given field
@@ -388,13 +387,7 @@
DateTimeShortcuts.calendars[num].drawNextMonth();
},
handleCalendarCallback: function(num) {
let format = get_format('DATE_INPUT_FORMATS')[0];
// the format needs to be escaped a little
format = format.replace('\\', '\\\\')
.replace('\r', '\\r')
.replace('\n', '\\n')
.replace('\t', '\\t')
.replace("'", "\\'");
const format = get_format('DATE_INPUT_FORMATS')[0];
return function(y, m, d) {
DateTimeShortcuts.calendarInputs[num].value = new Date(y, m - 1, d).strftime(format);
DateTimeShortcuts.calendarInputs[num].focus();

View File

@@ -4,14 +4,43 @@
'use strict';
{
const $ = django.jQuery;
let popupIndex = 0;
const relatedWindows = [];
function dismissChildPopups() {
relatedWindows.forEach(function(win) {
if(!win.closed) {
win.dismissChildPopups();
win.close();
}
});
}
function setPopupIndex() {
if(document.getElementsByName("_popup").length > 0) {
const index = window.name.lastIndexOf("__") + 2;
popupIndex = parseInt(window.name.substring(index));
} else {
popupIndex = 0;
}
}
function addPopupIndex(name) {
return name + "__" + (popupIndex + 1);
}
function removePopupIndex(name) {
return name.replace(new RegExp("__" + (popupIndex + 1) + "$"), '');
}
function showAdminPopup(triggeringLink, name_regexp, add_popup) {
const name = triggeringLink.id.replace(name_regexp, '');
const name = addPopupIndex(triggeringLink.id.replace(name_regexp, ''));
const href = new URL(triggeringLink.href);
if (add_popup) {
href.searchParams.set('_popup', 1);
}
const win = window.open(href, name, 'height=500,width=800,resizable=yes,scrollbars=yes');
relatedWindows.push(win);
win.focus();
return false;
}
@@ -21,12 +50,17 @@
}
function dismissRelatedLookupPopup(win, chosenId) {
const name = win.name;
const name = removePopupIndex(win.name);
const elem = document.getElementById(name);
if (elem.classList.contains('vManyToManyRawIdAdminField') && elem.value) {
elem.value += ',' + chosenId;
} else {
document.getElementById(name).value = chosenId;
elem.value = chosenId;
}
$(elem).trigger('change');
const index = relatedWindows.indexOf(win);
if (index > -1) {
relatedWindows.splice(index, 1);
}
win.close();
}
@@ -46,19 +80,57 @@
siblings.each(function() {
const elm = $(this);
elm.attr('href', elm.attr('data-href-template').replace('__fk__', value));
elm.removeAttr('aria-disabled');
});
} else {
siblings.removeAttr('href');
siblings.attr('aria-disabled', true);
}
}
function updateRelatedSelectsOptions(currentSelect, win, objId, newRepr, newId, skipIds = []) {
// After create/edit a model from the options next to the current
// select (+ or :pencil:) update ForeignKey PK of the rest of selects
// in the page.
const path = win.location.pathname;
// Extract the model from the popup url '.../<model>/add/' or
// '.../<model>/<id>/change/' depending the action (add or change).
const modelName = path.split('/')[path.split('/').length - (objId ? 4 : 3)];
// Select elements with a specific model reference and context of "available-source".
const selectsRelated = document.querySelectorAll(`[data-model-ref="${modelName}"] [data-context="available-source"]`);
selectsRelated.forEach(function(select) {
if (currentSelect === select || skipIds && skipIds.includes(select.id)) {
return;
}
let option = select.querySelector(`option[value="${objId}"]`);
if (!option) {
option = new Option(newRepr, newId);
select.options.add(option);
// Update SelectBox cache for related fields.
if (window.SelectBox !== undefined && !SelectBox.cache[currentSelect.id]) {
SelectBox.add_to_cache(select.id, option);
SelectBox.redisplay(select.id);
}
return;
}
option.textContent = newRepr;
option.value = newId;
});
}
function dismissAddRelatedObjectPopup(win, newId, newRepr) {
const name = win.name;
const name = removePopupIndex(win.name);
const elem = document.getElementById(name);
if (elem) {
const elemName = elem.nodeName.toUpperCase();
if (elemName === 'SELECT') {
elem.options[elem.options.length] = new Option(newRepr, newId, true, true);
updateRelatedSelectsOptions(elem, win, null, newRepr, newId);
} else if (elemName === 'INPUT') {
if (elem.classList.contains('vManyToManyRawIdAdminField') && elem.value) {
elem.value += ',' + newId;
@@ -70,15 +142,24 @@
$(elem).trigger('change');
} else {
const toId = name + "_to";
const toElem = document.getElementById(toId);
const o = new Option(newRepr, newId);
SelectBox.add_to_cache(toId, o);
SelectBox.redisplay(toId);
if (toElem && toElem.nodeName.toUpperCase() === 'SELECT') {
const skipIds = [name + "_from"];
updateRelatedSelectsOptions(toElem, win, null, newRepr, newId, skipIds);
}
}
const index = relatedWindows.indexOf(win);
if (index > -1) {
relatedWindows.splice(index, 1);
}
win.close();
}
function dismissChangeRelatedObjectPopup(win, objId, newRepr, newId) {
const id = win.name.replace(/^edit_/, '');
const id = removePopupIndex(win.name.replace(/^edit_/, ''));
const selectsSelector = interpolate('#%s, #%s_from, #%s_to', [id, id, id]);
const selects = $(selectsSelector);
selects.find('option').each(function() {
@@ -86,18 +167,23 @@
this.textContent = newRepr;
this.value = newId;
}
});
}).trigger('change');
updateRelatedSelectsOptions(selects[0], win, objId, newRepr, newId);
selects.next().find('.select2-selection__rendered').each(function() {
// The element can have a clear button as a child.
// Use the lastChild to modify only the displayed value.
this.lastChild.textContent = newRepr;
this.title = newRepr;
});
const index = relatedWindows.indexOf(win);
if (index > -1) {
relatedWindows.splice(index, 1);
}
win.close();
}
function dismissDeleteRelatedObjectPopup(win, objId) {
const id = win.name.replace(/^delete_/, '');
const id = removePopupIndex(win.name.replace(/^delete_/, ''));
const selectsSelector = interpolate('#%s, #%s_from, #%s_to', [id, id, id]);
const selects = $(selectsSelector);
selects.find('option').each(function() {
@@ -105,6 +191,10 @@
$(this).remove();
}
}).trigger('change');
const index = relatedWindows.indexOf(win);
if (index > -1) {
relatedWindows.splice(index, 1);
}
win.close();
}
@@ -115,17 +205,24 @@
window.dismissAddRelatedObjectPopup = dismissAddRelatedObjectPopup;
window.dismissChangeRelatedObjectPopup = dismissChangeRelatedObjectPopup;
window.dismissDeleteRelatedObjectPopup = dismissDeleteRelatedObjectPopup;
window.dismissChildPopups = dismissChildPopups;
window.relatedWindows = relatedWindows;
// Kept for backward compatibility
window.showAddAnotherPopup = showRelatedObjectPopup;
window.dismissAddAnotherPopup = dismissAddRelatedObjectPopup;
window.addEventListener('unload', function(evt) {
window.dismissChildPopups();
});
$(document).ready(function() {
setPopupIndex();
$("a[data-popup-opener]").on('click', function(event) {
event.preventDefault();
opener.dismissRelatedLookupPopup(window, $(this).data("popup-opener"));
});
$('body').on('click', '.related-widget-wrapper-link', function(e) {
$('body').on('click', '.related-widget-wrapper-link[data-popup="yes"]', function(e) {
e.preventDefault();
if (this.href) {
const event = $.Event('django:show-related', {href: this.href});

View File

@@ -27,9 +27,7 @@
$('.admin-autocomplete').not('[name*=__prefix__]').djangoAdminSelect2();
});
$(document).on('formset:added', (function() {
return function(event, $newFormset) {
return $newFormset.find('.admin-autocomplete').djangoAdminSelect2();
};
})(this));
document.addEventListener('formset:added', (event) => {
$(event.target).find('.admin-autocomplete').djangoAdminSelect2();
});
}

View File

@@ -36,6 +36,24 @@ depends on core.js for utility functions like removeChildren or quickElement
pgettext('abbrev. month December', 'Dec')
],
daysOfWeek: [
gettext('Sunday'),
gettext('Monday'),
gettext('Tuesday'),
gettext('Wednesday'),
gettext('Thursday'),
gettext('Friday'),
gettext('Saturday')
],
daysOfWeekAbbrev: [
pgettext('abbrev. day Sunday', 'Sun'),
pgettext('abbrev. day Monday', 'Mon'),
pgettext('abbrev. day Tuesday', 'Tue'),
pgettext('abbrev. day Wednesday', 'Wed'),
pgettext('abbrev. day Thursday', 'Thur'),
pgettext('abbrev. day Friday', 'Fri'),
pgettext('abbrev. day Saturday', 'Sat')
],
daysOfWeekInitial: [
pgettext('one letter Sunday', 'S'),
pgettext('one letter Monday', 'M'),
pgettext('one letter Tuesday', 'T'),
@@ -98,7 +116,7 @@ depends on core.js for utility functions like removeChildren or quickElement
// Draw days-of-week header
let tableRow = quickElement('tr', tableBody);
for (let i = 0; i < 7; i++) {
quickElement('th', tableRow, CalendarNamespace.daysOfWeek[(i + CalendarNamespace.firstDayOfWeek) % 7]);
quickElement('th', tableRow, CalendarNamespace.daysOfWeekInitial[(i + CalendarNamespace.firstDayOfWeek) % 7]);
}
const startingPos = new Date(year, month - 1, 1 - CalendarNamespace.firstDayOfWeek).getDay();

View File

@@ -1,43 +0,0 @@
/*global gettext*/
'use strict';
{
window.addEventListener('load', function() {
// Add anchor tag for Show/Hide link
const fieldsets = document.querySelectorAll('fieldset.collapse');
for (const [i, elem] of fieldsets.entries()) {
// Don't hide if fields in this fieldset have errors
if (elem.querySelectorAll('div.errors, ul.errorlist').length === 0) {
elem.classList.add('collapsed');
const h2 = elem.querySelector('h2');
const link = document.createElement('a');
link.id = 'fieldsetcollapser' + i;
link.className = 'collapse-toggle';
link.href = '#';
link.textContent = gettext('Show');
h2.appendChild(document.createTextNode(' ('));
h2.appendChild(link);
h2.appendChild(document.createTextNode(')'));
}
}
// Add toggle to hide/show anchor tag
const toggleFunc = function(ev) {
if (ev.target.matches('.collapse-toggle')) {
ev.preventDefault();
ev.stopPropagation();
const fieldset = ev.target.closest('fieldset');
if (fieldset.classList.contains('collapsed')) {
// Show
ev.target.textContent = gettext('Hide');
fieldset.classList.remove('collapsed');
} else {
// Hide
ev.target.textContent = gettext('Show');
fieldset.classList.add('collapsed');
}
}
};
document.querySelectorAll('fieldset.module').forEach(function(el) {
el.addEventListener('click', toggleFunc);
});
});
}

View File

@@ -85,6 +85,18 @@ function findPosY(obj) {
return (this.getSeconds() < 10) ? '0' + this.getSeconds() : this.getSeconds();
};
Date.prototype.getAbbrevDayName = function() {
return typeof window.CalendarNamespace === "undefined"
? '0' + this.getDay()
: window.CalendarNamespace.daysOfWeekAbbrev[this.getDay()];
};
Date.prototype.getFullDayName = function() {
return typeof window.CalendarNamespace === "undefined"
? '0' + this.getDay()
: window.CalendarNamespace.daysOfWeek[this.getDay()];
};
Date.prototype.getAbbrevMonthName = function() {
return typeof window.CalendarNamespace === "undefined"
? this.getTwoDigitMonth()
@@ -99,6 +111,8 @@ function findPosY(obj) {
Date.prototype.strftime = function(format) {
const fields = {
a: this.getAbbrevDayName(),
A: this.getFullDayName(),
b: this.getAbbrevMonthName(),
B: this.getFullMonthName(),
c: this.toString(),
@@ -119,11 +133,11 @@ function findPosY(obj) {
let result = '', i = 0;
while (i < format.length) {
if (format.charAt(i) === '%') {
result = result + fields[format.charAt(i + 1)];
result += fields[format.charAt(i + 1)];
++i;
}
else {
result = result + format.charAt(i);
result += format.charAt(i);
}
++i;
}

View File

@@ -0,0 +1,30 @@
/**
* Persist changelist filters state (collapsed/expanded).
*/
'use strict';
{
// Init filters.
let filters = JSON.parse(sessionStorage.getItem('django.admin.filtersState'));
if (!filters) {
filters = {};
}
Object.entries(filters).forEach(([key, value]) => {
const detailElement = document.querySelector(`[data-filter-title='${CSS.escape(key)}']`);
// Check if the filter is present, it could be from other view.
if (detailElement) {
value ? detailElement.setAttribute('open', '') : detailElement.removeAttribute('open');
}
});
// Save filter state when clicks.
const details = document.querySelectorAll('details');
details.forEach(detail => {
detail.addEventListener('toggle', event => {
filters[`${event.target.dataset.filterTitle}`] = detail.open;
sessionStorage.setItem('django.admin.filtersState', JSON.stringify(filters));
});
});
}

View File

@@ -50,11 +50,11 @@
// If forms are laid out as table rows, insert the
// "add" button in a new table row:
const numCols = $this.eq(-1).children().length;
$parent.append('<tr class="' + options.addCssClass + '"><td colspan="' + numCols + '"><a href="#">' + options.addText + "</a></tr>");
$parent.append('<tr class="' + options.addCssClass + '"><td colspan="' + numCols + '"><a role="button" class="addlink" href="#">' + options.addText + "</a></tr>");
addButton = $parent.find("tr:last a");
} else {
// Otherwise, insert it immediately after the last form:
$this.filter(":last").after('<div class="' + options.addCssClass + '"><a href="#">' + options.addText + "</a></div>");
$this.filter(":last").after('<div class="' + options.addCssClass + '"><a role="button" class="addlink" href="#">' + options.addText + "</a></div>");
addButton = $this.filter(":last").next().find("a");
}
}
@@ -88,7 +88,12 @@
if (options.added) {
options.added(row);
}
$(document).trigger('formset:added', [row, options.prefix]);
row.get(0).dispatchEvent(new CustomEvent("formset:added", {
bubbles: true,
detail: {
formsetName: options.prefix
}
}));
};
/**
@@ -99,15 +104,15 @@
if (row.is("tr")) {
// If the forms are laid out in table rows, insert
// the remove button into the last table cell:
row.children(":last").append('<div><a class="' + options.deleteCssClass + '" href="#">' + options.deleteText + "</a></div>");
row.children(":last").append('<div><a role="button" class="' + options.deleteCssClass + '" href="#">' + options.deleteText + "</a></div>");
} else if (row.is("ul") || row.is("ol")) {
// If they're laid out as an ordered/unordered list,
// insert an <li> after the last list item:
row.append('<li><a class="' + options.deleteCssClass + '" href="#">' + options.deleteText + "</a></li>");
row.append('<li><a role="button" class="' + options.deleteCssClass + '" href="#">' + options.deleteText + "</a></li>");
} else {
// Otherwise, just insert the remove button as the
// last child element of the form's container:
row.children(":first").append('<span><a class="' + options.deleteCssClass + '" href="#">' + options.deleteText + "</a></span>");
row.children(":first").append('<span><a role="button" class="' + options.deleteCssClass + '" href="#">' + options.deleteText + "</a></span>");
}
// Add delete handler for each row.
row.find("a." + options.deleteCssClass).on('click', inlineDeleteHandler.bind(this));
@@ -130,7 +135,11 @@
if (options.removed) {
options.removed(row);
}
$(document).trigger('formset:removed', [row, options.prefix]);
document.dispatchEvent(new CustomEvent("formset:removed", {
detail: {
formsetName: options.prefix
}
}));
// Update the TOTAL_FORMS form count.
const forms = $("." + options.formCssClass);
$("#id_" + options.prefix + "-TOTAL_FORMS").val(forms.length);
@@ -296,7 +305,13 @@
dependency_list = input.data('dependency_list') || [],
dependencies = [];
$.each(dependency_list, function(i, field_name) {
dependencies.push('#' + row.find('.form-row .field-' + field_name).find('input, select, textarea').attr('id'));
// Dependency in a fieldset.
let field_element = row.find('.form-row .field-' + field_name);
// Dependency without a fieldset.
if (!field_element.length) {
field_element = row.find('.form-row.field-' + field_name);
}
dependencies.push('#' + field_element.find('input, select, textarea').attr('id'));
});
if (dependencies.length) {
input.prepopulate(dependencies, input.attr('maxlength'));

View File

@@ -2,47 +2,24 @@
{
const toggleNavSidebar = document.getElementById('toggle-nav-sidebar');
if (toggleNavSidebar !== null) {
const navLinks = document.querySelectorAll('#nav-sidebar a');
function disableNavLinkTabbing() {
for (const navLink of navLinks) {
navLink.tabIndex = -1;
}
}
function enableNavLinkTabbing() {
for (const navLink of navLinks) {
navLink.tabIndex = 0;
}
}
function disableNavFilterTabbing() {
document.getElementById('nav-filter').tabIndex = -1;
}
function enableNavFilterTabbing() {
document.getElementById('nav-filter').tabIndex = 0;
}
const navSidebar = document.getElementById('nav-sidebar');
const main = document.getElementById('main');
let navSidebarIsOpen = localStorage.getItem('django.admin.navSidebarIsOpen');
if (navSidebarIsOpen === null) {
navSidebarIsOpen = 'true';
}
if (navSidebarIsOpen === 'false') {
disableNavLinkTabbing();
disableNavFilterTabbing();
}
main.classList.toggle('shifted', navSidebarIsOpen === 'true');
navSidebar.setAttribute('aria-expanded', navSidebarIsOpen);
toggleNavSidebar.addEventListener('click', function() {
if (navSidebarIsOpen === 'true') {
navSidebarIsOpen = 'false';
disableNavLinkTabbing();
disableNavFilterTabbing();
} else {
navSidebarIsOpen = 'true';
enableNavLinkTabbing();
enableNavFilterTabbing();
}
localStorage.setItem('django.admin.navSidebarIsOpen', navSidebarIsOpen);
main.classList.toggle('shifted');
navSidebar.setAttribute('aria-expanded', navSidebarIsOpen);
});
}

View File

@@ -1,4 +1,3 @@
/*global opener */
'use strict';
{
const initData = JSON.parse(document.getElementById('django-admin-popup-response-constants').dataset.popupResponse);

View File

@@ -3,7 +3,11 @@
const $ = django.jQuery;
const fields = $('#django-admin-prepopulated-fields-constants').data('prepopulatedFields');
$.each(fields, function(index, field) {
$('.empty-form .form-row .field-' + field.name + ', .empty-form.form-row .field-' + field.name).addClass('prepopulated_field');
$(
'.empty-form .form-row .field-' + field.name +
', .empty-form.form-row .field-' + field.name +
', .empty-form .form-row.field-' + field.name
).addClass('prepopulated_field');
$(field.id).data('dependency_list', field.dependency_list).prepopulate(
field.dependency_ids, field.maxLength, field.allowUnicode
);

51
assets/admin/js/theme.js Normal file
View File

@@ -0,0 +1,51 @@
'use strict';
{
function setTheme(mode) {
if (mode !== "light" && mode !== "dark" && mode !== "auto") {
console.error(`Got invalid theme mode: ${mode}. Resetting to auto.`);
mode = "auto";
}
document.documentElement.dataset.theme = mode;
localStorage.setItem("theme", mode);
}
function cycleTheme() {
const currentTheme = localStorage.getItem("theme") || "auto";
const prefersDark = window.matchMedia("(prefers-color-scheme: dark)").matches;
if (prefersDark) {
// Auto (dark) -> Light -> Dark
if (currentTheme === "auto") {
setTheme("light");
} else if (currentTheme === "light") {
setTheme("dark");
} else {
setTheme("auto");
}
} else {
// Auto (light) -> Dark -> Light
if (currentTheme === "auto") {
setTheme("dark");
} else if (currentTheme === "dark") {
setTheme("light");
} else {
setTheme("auto");
}
}
}
function initTheme() {
// set theme defined in localStorage if there is one, or fallback to auto mode
const currentTheme = localStorage.getItem("theme");
currentTheme ? setTheme(currentTheme) : setTheme("auto");
}
window.addEventListener('load', function(_) {
const buttons = document.getElementsByClassName("theme-toggle");
Array.from(buttons).forEach((btn) => {
btn.addEventListener("click", cycleTheme);
});
});
initTheme();
}

View File

@@ -0,0 +1,29 @@
"use strict";
// Fallback JS for browsers which do not support :has selector used in
// admin/css/unusable_password_fields.css
// Remove file once all supported browsers support :has selector
try {
// If browser does not support :has selector this will raise an error
document.querySelector("form:has(input)");
} catch (error) {
console.log("Defaulting to javascript for usable password form management: " + error);
// JS replacement for unsupported :has selector
document.querySelectorAll('input[name="usable_password"]').forEach(option => {
option.addEventListener('change', function() {
const usablePassword = (this.value === "true" ? this.checked : !this.checked);
const submit1 = document.querySelector('input[type="submit"].set-password');
const submit2 = document.querySelector('input[type="submit"].unset-password');
const messages = document.querySelector('#id_unusable_warning');
document.getElementById('id_password1').closest('.form-row').hidden = !usablePassword;
document.getElementById('id_password2').closest('.form-row').hidden = !usablePassword;
if (messages) {
messages.hidden = usablePassword;
}
if (submit1 && submit2) {
submit1.hidden = !usablePassword;
submit2.hidden = usablePassword;
}
});
option.dispatchEvent(new Event('change'));
});
}

View File

@@ -163,8 +163,7 @@
s = s.replace(/^\s+|\s+$/g, ''); // trim leading/trailing spaces
s = s.replace(/[-\s]+/g, '-'); // convert spaces to hyphens
s = s.substring(0, num_chars); // trim to first num_chars chars
s = s.replace(/-+$/g, ''); // trim any trailing hyphens
return s;
return s.replace(/-+$/g, ''); // trim any trailing hyphens
}
window.URLify = URLify;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@@ -1,6 +1,6 @@
The MIT License
Copyright (c) 2007-2017 Steven Levithan <http://xregexp.com/>
Copyright (c) 2007-present Steven Levithan <http://xregexp.com/>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -24,7 +24,7 @@
function initialiseCKEditor() {
var textareas = Array.prototype.slice.call(
document.querySelectorAll("textarea[data-type=ckeditortype]")
document.querySelectorAll("textarea[data-type=ckeditortype]"),
)
for (var i = 0; i < textareas.length; ++i) {
var t = textareas[i]

View File

@@ -0,0 +1,19 @@
/* Fix for Django dark theme background */
/* See https://github.com/django-ckeditor/django-ckeditor/issues/670 */
.cke_reset_all tr:nth-child(even),
.cke_reset_all tr:nth-child(odd),
.cke_reset_all .row-form-errors,
.cke_reset_all tr:nth-child(even) .errorlist,
.cke_reset_all tr:nth-child(odd) + .row-form-errors,
.cke_reset_all tr:nth-child(odd) + .row-form-errors .errorlist,
.cke_reset_all input[type="text"],
.cke_reset_all input[type="password"] {
background: inherit;
color: inherit;
}
/* Fix for CKEditor source editor with Django dark theme */
/* See https://github.com/django-ckeditor/django-ckeditor/issues/741 */
textarea.cke_source {
color: revert;
}

Some files were not shown because too many files have changed in this diff Show More