new gallery implementation
@@ -83,6 +83,7 @@ INSTALLED_APPS = [
|
||||
"documents.apps.DocumentsConfig",
|
||||
"blackboard.apps.BlackboardConfig",
|
||||
"tasks.apps.TasksConfig",
|
||||
"gallery.apps.GalleryConfig",
|
||||
]
|
||||
|
||||
MIDDLEWARE = [
|
||||
@@ -184,7 +185,11 @@ if DEBUG:
|
||||
else:
|
||||
STATIC_URL = "/assets/"
|
||||
|
||||
STATICFILES_DIRS = [os.path.join(BASE_DIR, "static")]
|
||||
STATICFILES_DIRS = [
|
||||
os.path.join(BASE_DIR, "gallery/static"),
|
||||
os.path.join(BASE_DIR, "static"),
|
||||
]
|
||||
|
||||
STATIC_ROOT = "assets/"
|
||||
MEDIA_ROOT = os.path.join(BASE_DIR, "files/")
|
||||
MEDIA_URL = "/files/"
|
||||
|
||||
@@ -35,6 +35,7 @@ urlpatterns = [
|
||||
path("api/", include(router.urls)),
|
||||
path("blackboard/", include("blackboard.urls"), name="blackboard"),
|
||||
path("ckeditor/", include("ckeditor_uploader.urls")),
|
||||
path("gallery/", include("gallery.urls"), name="gallery"),
|
||||
path("index.html", views.index, name="home"),
|
||||
path("jobs/", include(jobs_urlpatterns), name="jobs"),
|
||||
path("members/", include("members.urls"), name="members"),
|
||||
|
||||
0
fet2020/gallery/__init__.py
Normal file
16
fet2020/gallery/admin.py
Normal file
@@ -0,0 +1,16 @@
|
||||
from django.contrib import admin
|
||||
|
||||
from .forms import AlbumAdminForm
|
||||
from .models import Album
|
||||
|
||||
|
||||
class AlbumAdmin(admin.ModelAdmin):
|
||||
form = AlbumAdminForm
|
||||
model = Album
|
||||
|
||||
def save_model(self, request, obj, form, change):
|
||||
obj.author = request.user
|
||||
super().save_model(request, obj, form, change)
|
||||
|
||||
|
||||
admin.site.register(Album, AlbumAdmin)
|
||||
5
fet2020/gallery/apps.py
Normal file
@@ -0,0 +1,5 @@
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class GalleryConfig(AppConfig):
|
||||
name = "gallery"
|
||||
13
fet2020/gallery/forms.py
Normal file
@@ -0,0 +1,13 @@
|
||||
from ckeditor_uploader.widgets import CKEditorUploadingWidget
|
||||
from django import forms
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from .models import Album
|
||||
|
||||
|
||||
class AlbumAdminForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = Album
|
||||
fields = "__all__"
|
||||
|
||||
widgets = {"description": CKEditorUploadingWidget(config_name="default")}
|
||||
51
fet2020/gallery/models.py
Normal file
@@ -0,0 +1,51 @@
|
||||
from django.contrib.auth.models import User
|
||||
from django.db import models
|
||||
from django.urls import reverse
|
||||
from django.utils import timezone
|
||||
from django.utils.text import slugify
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
|
||||
class Album(models.Model):
|
||||
title = models.CharField(verbose_name="Titel", max_length=200)
|
||||
slug = models.SlugField(unique=True, null=True, blank=True)
|
||||
|
||||
folder_path = models.CharField(verbose_name="Ordner Path", max_length=200)
|
||||
thumbnail = models.CharField(
|
||||
verbose_name="Thumbnail", max_length=200, null=True, blank=True
|
||||
)
|
||||
|
||||
photographer = models.ForeignKey(
|
||||
User, on_delete=models.SET_NULL, null=True, blank=True
|
||||
)
|
||||
|
||||
description = models.TextField(null=True, blank=True)
|
||||
|
||||
STATUS = (
|
||||
("10", "DRAFT"),
|
||||
("20", "PUBLIC"),
|
||||
)
|
||||
status = models.CharField(max_length=2, choices=STATUS, default="10")
|
||||
|
||||
public_date = models.DateField(
|
||||
verbose_name="Veröffentlichung", null=True, blank=True, default=timezone.now
|
||||
)
|
||||
|
||||
# Managers
|
||||
objects = models.Manager()
|
||||
|
||||
class Meta:
|
||||
verbose_name = _("Album")
|
||||
verbose_name_plural = _("Alben")
|
||||
|
||||
def __str__(self):
|
||||
return self.title
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse("album", kwargs={"slug": self.slug})
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
if not self.slug:
|
||||
self.slug = slugify(self.title)
|
||||
|
||||
super().save(*args, **kwargs)
|
||||
1
fet2020/gallery/static/Gallery-3.3.0/.github/FUNDING.yml
vendored
Normal file
@@ -0,0 +1 @@
|
||||
github: [blueimp]
|
||||
25
fet2020/gallery/static/Gallery-3.3.0/.github/workflows/nodejs.yml
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
name: Node CI
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [10.x, 12.x]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
- name: npm install, build, and test
|
||||
run: |
|
||||
npm install
|
||||
npm run build --if-present
|
||||
npm test
|
||||
env:
|
||||
CI: true
|
||||
1
fet2020/gallery/static/Gallery-3.3.0/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
node_modules
|
||||
23
fet2020/gallery/static/Gallery-3.3.0/LICENSE.txt
Normal file
@@ -0,0 +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.
|
||||
1449
fet2020/gallery/static/Gallery-3.3.0/README.md
Normal file
@@ -0,0 +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;
|
||||
}
|
||||
@@ -0,0 +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;
|
||||
}
|
||||
249
fet2020/gallery/static/Gallery-3.3.0/css/blueimp-gallery.css
Normal file
@@ -0,0 +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;
|
||||
}
|
||||
}
|
||||
2
fet2020/gallery/static/Gallery-3.3.0/css/blueimp-gallery.min.css
vendored
Normal file
@@ -0,0 +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"}
|
||||
78
fet2020/gallery/static/Gallery-3.3.0/css/demo/demo.css
Normal file
@@ -0,0 +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: ' | ';
|
||||
}
|
||||
}
|
||||
BIN
fet2020/gallery/static/Gallery-3.3.0/img/close.png
Normal file
|
After Width: | Height: | Size: 163 B |
4
fet2020/gallery/static/Gallery-3.3.0/img/close.svg
Normal file
@@ -0,0 +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>
|
||||
|
After Width: | Height: | Size: 258 B |
BIN
fet2020/gallery/static/Gallery-3.3.0/img/error.png
Normal file
|
After Width: | Height: | Size: 1.0 KiB |
6
fet2020/gallery/static/Gallery-3.3.0/img/error.svg
Normal file
@@ -0,0 +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>
|
||||
|
After Width: | Height: | Size: 394 B |
BIN
fet2020/gallery/static/Gallery-3.3.0/img/loading.gif
Normal file
|
After Width: | Height: | Size: 3.7 KiB |
52
fet2020/gallery/static/Gallery-3.3.0/img/loading.svg
Normal file
@@ -0,0 +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>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.4 KiB |
BIN
fet2020/gallery/static/Gallery-3.3.0/img/next.png
Normal file
|
After Width: | Height: | Size: 166 B |
4
fet2020/gallery/static/Gallery-3.3.0/img/next.svg
Normal file
@@ -0,0 +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>
|
||||
|
After Width: | Height: | Size: 194 B |
BIN
fet2020/gallery/static/Gallery-3.3.0/img/play-pause.png
Normal file
|
After Width: | Height: | Size: 432 B |
6
fet2020/gallery/static/Gallery-3.3.0/img/play-pause.svg
Normal file
@@ -0,0 +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>
|
||||
|
After Width: | Height: | Size: 434 B |
BIN
fet2020/gallery/static/Gallery-3.3.0/img/prev.png
Normal file
|
After Width: | Height: | Size: 170 B |
4
fet2020/gallery/static/Gallery-3.3.0/img/prev.svg
Normal file
@@ -0,0 +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>
|
||||
|
After Width: | Height: | Size: 194 B |
BIN
fet2020/gallery/static/Gallery-3.3.0/img/video-play.png
Normal file
|
After Width: | Height: | Size: 993 B |
5
fet2020/gallery/static/Gallery-3.3.0/img/video-play.svg
Normal file
@@ -0,0 +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>
|
||||
|
After Width: | Height: | Size: 271 B |
158
fet2020/gallery/static/Gallery-3.3.0/index.html
Normal file
@@ -0,0 +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 & 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">© 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>
|
||||
@@ -0,0 +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
|
||||
})
|
||||
@@ -0,0 +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
|
||||
})
|
||||
188
fet2020/gallery/static/Gallery-3.3.0/js/blueimp-gallery-video.js
Normal file
@@ -0,0 +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
|
||||
})
|
||||
212
fet2020/gallery/static/Gallery-3.3.0/js/blueimp-gallery-vimeo.js
Normal file
@@ -0,0 +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
|
||||
})
|
||||
@@ -0,0 +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
|
||||
})
|
||||
1551
fet2020/gallery/static/Gallery-3.3.0/js/blueimp-gallery.js
Normal file
2
fet2020/gallery/static/Gallery-3.3.0/js/blueimp-gallery.min.js
vendored
Normal file
217
fet2020/gallery/static/Gallery-3.3.0/js/blueimp-helper.js
Normal file
@@ -0,0 +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
|
||||
}
|
||||
})()
|
||||
140
fet2020/gallery/static/Gallery-3.3.0/js/demo/demo.js
Normal file
@@ -0,0 +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)
|
||||
})
|
||||
})
|
||||
@@ -0,0 +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)
|
||||
})
|
||||
})
|
||||
2
fet2020/gallery/static/Gallery-3.3.0/js/jquery.blueimp-gallery.min.js
vendored
Normal file
11008
fet2020/gallery/static/Gallery-3.3.0/js/vendor/jquery.js
vendored
Normal file
2883
fet2020/gallery/static/Gallery-3.3.0/package-lock.json
generated
Normal file
98
fet2020/gallery/static/Gallery-3.3.0/package.json
Normal file
@@ -0,0 +1,98 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
3
fet2020/gallery/tests.py
Normal file
@@ -0,0 +1,3 @@
|
||||
from django.test import TestCase
|
||||
|
||||
# Create your tests here.
|
||||
9
fet2020/gallery/urls.py
Normal file
@@ -0,0 +1,9 @@
|
||||
from django.urls import path
|
||||
|
||||
from . import views
|
||||
|
||||
|
||||
urlpatterns = [
|
||||
path("", views.index, name="gallery"),
|
||||
path("<slug:slug>/", views.show_album, name="album"),
|
||||
]
|
||||
66
fet2020/gallery/views.py
Normal file
@@ -0,0 +1,66 @@
|
||||
import os
|
||||
|
||||
from django.http import HttpResponse
|
||||
from django.shortcuts import render
|
||||
|
||||
from .models import Album
|
||||
|
||||
|
||||
def __get_image_list(file_path):
|
||||
img_list = []
|
||||
|
||||
if os.path.exists(file_path):
|
||||
for f in os.listdir(file_path):
|
||||
ext = os.path.splitext(f)[1]
|
||||
valid_images = [".jpg", ".png"]
|
||||
|
||||
if ext.lower() not in valid_images:
|
||||
continue
|
||||
|
||||
img_list.append(f)
|
||||
|
||||
return img_list
|
||||
|
||||
|
||||
def index(request):
|
||||
|
||||
_base_dir = "/home/project/fet2020/fet2020"
|
||||
_path = "/static/images/"
|
||||
|
||||
if request.user.is_authenticated:
|
||||
albums = Album.objects.all()
|
||||
else:
|
||||
albums = Album.objects.filter(status="20")
|
||||
|
||||
for album in albums:
|
||||
if not album.thumbnail:
|
||||
file_path = os.path.join(_base_dir + _path, album.folder_path)
|
||||
img_list = __get_image_list(file_path)
|
||||
if img_list:
|
||||
album.thumbnail = img_list[0]
|
||||
|
||||
context = {
|
||||
"albums": albums,
|
||||
"path": _path,
|
||||
}
|
||||
|
||||
return render(request, "gallery/index.html", context)
|
||||
|
||||
|
||||
def show_album(request, slug):
|
||||
|
||||
_base_dir = "/home/project/fet2020/fet2020"
|
||||
_path = "/static/images/"
|
||||
|
||||
album = Album.objects.filter(slug=slug).first()
|
||||
|
||||
file_path = os.path.join(_base_dir + _path, album.folder_path)
|
||||
img_list = __get_image_list(file_path)
|
||||
|
||||
context = {
|
||||
"album": album,
|
||||
"images": img_list,
|
||||
"path": _path,
|
||||
}
|
||||
|
||||
return render(request, "gallery/album.html", context)
|
||||
67
fet2020/templates/gallery/album.html
Normal file
@@ -0,0 +1,67 @@
|
||||
{% extends 'layout.html' %}
|
||||
{% load static %}
|
||||
{% load thumbnail %}
|
||||
|
||||
{% block galleryheader %}
|
||||
<link rel="stylesheet" href="{% static 'Gallery-3.3.0/css/blueimp-gallery.min.css' %}">
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<div class="grid-container">
|
||||
|
||||
<div class="grid-x padding-top-1">
|
||||
<a class="button" href="{% url 'gallery' %}">Zurück</a>
|
||||
</div>
|
||||
<hr>
|
||||
|
||||
<div class="grid-x">
|
||||
<div class="cell">
|
||||
{% if album.photographer %}
|
||||
Fotograf:<a href="{% url 'member' album.photographer.id %}"> {{ album.photographer | capfirst }}</a><br>
|
||||
{% endif %}
|
||||
Datum: {{ album.public_date }}<br>
|
||||
{% if album.status == "10" %}
|
||||
DRAFT<br>
|
||||
{% endif %}
|
||||
{% if album.description %}
|
||||
<p>
|
||||
{{ album.description }}
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
|
||||
<!-- The Gallery as lightbox dialog, should be a document body child element -->
|
||||
<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>
|
||||
|
||||
<div id="links" class="grid-x">
|
||||
{% for image in images %}
|
||||
<a id="{{ image }}" href="{{ path }}{{ album.folder_path }}/{{ image }}" title="{{ image }}" class="cell large-2 medium-3 small-12">
|
||||
<img src="{{ path }}{{ album.folder_path }}/{{ image }}" alt="{{ image }}">
|
||||
</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="{% static 'Gallery-3.3.0/js/blueimp-gallery.min.js' %}"></script>
|
||||
<script>
|
||||
document.getElementById('links').onclick = function (event) {
|
||||
event = event || window.event
|
||||
var target = event.target || event.srcElement
|
||||
var link = target.src ? target.parentNode : target
|
||||
var options = { index: link, event: event }
|
||||
var links = this.getElementsByTagName('a')
|
||||
blueimp.Gallery(links, options)
|
||||
}
|
||||
</script>
|
||||
|
||||
{% endblock %}
|
||||
23
fet2020/templates/gallery/index.html
Normal file
@@ -0,0 +1,23 @@
|
||||
{% extends 'layout.html' %}
|
||||
{% load static %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<div class="grid-container">
|
||||
<div class="grid-x">
|
||||
|
||||
{% for album in albums %}
|
||||
<div class="cell large-2 medium-3 small-12">
|
||||
|
||||
<a href="{% url 'album' album.slug %}">
|
||||
<img src="{{ path }}{{ album.folder_path }}/{{ album.thumbnail }}">
|
||||
{{ album.title }}
|
||||
</a>
|
||||
|
||||
</div>
|
||||
{% endfor %}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
@@ -12,6 +12,8 @@
|
||||
<link rel="stylesheet" href="{% static 'app.css' %}">
|
||||
<link rel="stylesheet" href="{% static 'fet.css' %}">
|
||||
<link href="{% static 'fontawesomefree/css/all.min.css' %}" rel="stylesheet" type="text/css">
|
||||
{% block galleryheader %}
|
||||
{% endblock %}
|
||||
{% block extraheader %}
|
||||
{% endblock %}
|
||||
</head>
|
||||
@@ -58,7 +60,7 @@
|
||||
<li><a class="button header-btn header-link" href="{% url 'posts:posts.index' %}">News</a></li>
|
||||
<!-- show active members first -->
|
||||
<li><a class="button header-btn header-link" href="{% url 'members_view' 'A' %}">Fachschaft</a></li>
|
||||
<li><a class="button header-btn header-link" href="/fotos/">Fotos</a></li>
|
||||
<li><a class="button header-btn header-link" href="{% url 'gallery' %}">Galerie</a></li>
|
||||
<li><a class="button header-btn header-link" href="{% url 'blackboard' %}">Blackboard</a></li>
|
||||
<li><a class="button header-btn header-link" href="{% url 'contact' %}">Kontakt</a></li>
|
||||
{% if request.user.is_authenticated %}
|
||||
|
||||