gallery blueimp

This commit is contained in:
Andreas Stephanides
2017-09-01 22:52:26 +02:00
parent 2d0f074315
commit bfdeda27be
43 changed files with 14849 additions and 107 deletions

View File

@@ -6,79 +6,49 @@ from flask_frozen import Freezer
from config import Config
import os
import re
from os.path import isfile, abspath
from utils import pjoin2
from utils import pjoin, list_dir, path_depth
from utils import path_depth, page_to_link, page_to_link, file_to_link
from functools import partial
from collections import namedtuple
from flatpages import FileLists
package_directory = os.path.dirname(os.path.abspath(__file__))
cfg = Config(file(os.path.join(package_directory, 'config.cfg')))
# Loading constants from config file
FLATPAGES_AUTO_RELOAD = cfg.pages_reload
FLATPAGES_AUTO_RELOAD = True
FLATPAGES_EXTENSION = '.md'
FLATPAGES_ROOT = abspath(cfg.pages_root)
FLATPAGES_FP_ROOT = abspath(cfg.pages_root)
FLATPAGES_ROOT = os.path.abspath(cfg.pages_root)
FLATPAGES_FP_ROOT = os.path.abspath(cfg.pages_root)
# Initialize application
app = Flask(__name__)
fp_cfg=dict(filter(lambda v: v[0].startswith("FLATPAGES"), zip(cfg, dict(cfg).values())))
app.config.from_object(__name__)
app.config.update(cfg)
FlatPagesIndex.FLATPAGES_ROOT=FLATPAGES_ROOT
flatpages = FlatPagesIndex(app)
flatpages.get('index')
freezer = Freezer(app)
app.config.from_object(__name__)
page_blueprint = Blueprint('intern', __name__)
# List all non *.md files within the directory
list_dir_md=partial(list_dir, not_ext=["md","~"])
# List all jpg images within the directory
list_dir_img=partial(list_dir, ext="jpg")
# List all subpages of the current page
get_sub_pages = partial(FlatPagesIndex.get_sub_pages, flatpages)
get_sub_ipages = partial(FlatPagesIndex.get_sub_ipages, flatpages)
def get_bc(path):
return flatpages.get_pages(FlatPagesIndex.breadcrumbs(path))
# return get_breadcrumb_pages(get_breadcrumb_paths(path))
# completes the meta hash if a configuration is not set
def page_defaults(page, is_index, path):
def page_defaults(page, path):
page.meta["title"]=page.meta.get("title", path.split('/')[-1])
page.meta["template"]=page.meta.get("template", cfg.default_template)
return page
def load_lists_for_templates(path, is_index):
path2 = pjoin(FLATPAGES_ROOT,path)
if is_index == True:
ld=list_dir_md(path2)
il=list_dir_img(path2)
sp=list(get_sub_pages(path))
spi=list(get_sub_ipages(path))
else:
ld=[]
sp=[]
spi=[]
il=[]
bc=get_bc(path)
return (ld, il, sp, spi,bc)
@page_blueprint.route('/<path:name>/')
@page_blueprint.route('/')
def post(name='index'):
is_index, path, page = flatpages.get_flatpage(name)
app.logger.info('render '+name)
if not page is None:
page=page_defaults(page, is_index, path)
ld, il, sp, spi, bc = load_lists_for_templates(path,is_index)
return render_template(page.meta["template"], ld=ld, post=page, sp=sp, spi=spi, il=il, pth=path, pagebreadcrumbs=bc)
page = page_defaults(page, path)
fl = linklist_dict_lists(flatpages.load_linklists_for_templates(page.path,path, is_index, page.meta,partial(url_for,'intern.post')))
return render_template(page.meta["template"], post=page,
pth=path, filelists=fl)
if os.path.exists(os.path.join(FLATPAGES_ROOT,path)):
return send_from_directory(FLATPAGES_ROOT,path)
else:
@@ -88,19 +58,33 @@ def post(name='index'):
def json_url_for(paths):
for p in paths:
yield url_for('intern.postjson', name=p)
def filelist_dict_lists(filelists):
return {"breadcrumbs": list(filelists.breadcrumbs),
"sub_index_pages": list(json_url_for(FlatPagesIndex.get_paths(filelists.sub_index_pages))),
"sub_pages": list(json_url_for(FlatPagesIndex.get_paths(filelists.sub_pages))),
"image_list": list(filelists.list_images)
}
def linklist_dict_lists(filelists):
return {"breadcrumbs": list(filelists.breadcrumbs),
"sub_index_pages": list(filelists.sub_index_pages ),
"sub_pages": list(filelists.sub_pages) ,
"image_list": list(filelists.list_images),
"file_list": list(filelists.list_files)
}
@page_blueprint.route('/<path:name>.json/')
def postjson(name='index'):
is_index, path, page = flatpages.get_flatpage(name)
if not page is None:
ld, il, sp, spi, bc = load_lists_for_templates(path, is_index)
page_defaults(page, is_index, path)
# filelists=flatpages.load_lists_for_templates(page.path, is_index,page.meta)
page=page_defaults(page, path)
p=page.meta
# p["links"]=linklist_dict_lists(flatpages.load_linklists_for_templates(page.path, path, is_index,page.meta))
p.update(linklist_dict_lists(flatpages.load_linklists_for_templates(page.path, path, is_index,page.meta)))
p["depth"]=path_depth(path)
p["path"]=path
p["breadcrumbs"]=list(bc)
p["subfolders"]=list(json_url_for(FlatPagesIndex.get_paths(spi)))
p["subpages"]= list(json_url_for(FlatPagesIndex.get_paths(sp)))
p["text"]=page.html
return jsonify(page=p)

View File

@@ -1,5 +1,6 @@
pages_root: 'data'
pages_reload: True
static_root: 'static'
default_template: 'page.html'
url_prefix: "/int"
url_prefix: "/int"
FLATPAGES_EXTENSION: ".md"
FLATPAGES_AUTO_RELOAD: True

View File

@@ -1,12 +1,25 @@
from flask_flatpages import FlatPages, pygments_style_defs
import flask_flatpages
from flask import url_for
import re
from utils import path_depth,pjoin2
from utils import path_depth,pjoin2,pjoin,list_dir, page_to_link, file_to_link
from functools import partial
from collections import namedtuple
FileLists=namedtuple("FileLists", ["list_files", "list_images", "sub_pages", "sub_index_pages", "breadcrumbs"])
# List all non *.md files within the directory
list_dir_md=partial(list_dir, not_ext=["md","~"])
# List all jpg images within the directory
list_dir_img=partial(list_dir, ext=["jpg", "jpeg","JPG"])
class FlatPagesIndex(FlatPages):
FLATPAGES_ROOT="."
@staticmethod
def get_breadcrumb_paths(path):
"""
@@ -14,23 +27,26 @@ class FlatPagesIndex(FlatPages):
a/b/index -> [a/index a/b/index]
"""
elements = path.split('/')
elements2 = ['index']
for i in range(1,len(elements)):
elements2.append(pjoin2(elements[0:i])+u'/index')
return elements2
print "i: %s" % elements
elements2 = ['index']
if len(elements)>2:
for i in range(1,len(elements)):
print "i: %s" % elements[0:i]
elements2.append(pjoin2(elements[0:i])+u'/index')
return elements2
def breadcrumbs(self, page):
"Parse a path or the path of a page into breadcrumbs"
if type(page) is flask_flatpages.Page:
return self.get_pages( FlatPagesIndex.get_breadcrumb_paths(page.path))
else:
return self.get_pages(FlatPagesIndex.get_breadcrumb_paths(page))
@staticmethod
def get_paths(pages):
return (p.path for p in pages)
@staticmethod
def breadcrumbs(page):
"Parse a path or the path of a page into breadcrumbs"
if type(page) is flask_flatpages.Page:
return FlatPagesIndex.get_breadcrumb_paths(page.path)
else:
return FlatPagesIndex.get_breadcrumb_paths(page)
def get_pages(self, paths):
if paths is None:
@@ -50,17 +66,17 @@ class FlatPagesIndex(FlatPages):
def get_sub_ipages(self, path):
cc=path_depth(path)
ppath="index" if path=="" else pjoin2([path,"index"])
ps=[p for p in self
ps=(p for p in self
if (p.path.startswith(path) and # subpages of this page
not ( re.match('.*index',p.path) is None) and # only index
( ppath != p.path) and # not identical page
len(p.path.split('/'))<=cc+2) ] # only one level
len(p.path.split('/'))<=cc+2) ) # only one level
return ps
# load a page from a path information
def get_flatpage(self,path):
is_index= path=='' or path.split('/')[-1]=='index'
is_index = path=='' or path.split('/')[-1]=='index'
if path == 'index' or path=='':
is_index=True
path=''
@@ -77,18 +93,54 @@ class FlatPagesIndex(FlatPages):
page=FlatPages.get(self,path)
return (is_index, path, page)
def load_lists_for_templates(self, path, is_index):
path2 = pjoin(FLATPAGES_ROOT,path)
def load_linklists_for_templates(self,page_path, rel_path, is_index=True, cfg={}, page_url_for=partial(url_for,'intern.postjson')):
abspath = pjoin(FlatPagesIndex.FLATPAGES_ROOT,rel_path)
# if not is_index:
dirpath= pjoin(FlatPagesIndex.FLATPAGES_ROOT,"/".join(page_path.split('/')[:-1]))
bc = page_to_link( self.breadcrumbs(page_path), page_url_for)
il=[]
if (cfg.get("has_img",False) ):
il=file_to_link(list_dir_img(dirpath), page_url_for)
if is_index == True:
ld,sp,spi=(file_to_link(list_dir_md(abspath),page_url_for),
page_to_link(self.get_sub_pages(rel_path),page_url_for),
page_to_link(self.get_sub_ipages(rel_path),page_url_for))
else:
ld,sp,spi=([],[],[])
fl=FileLists(list_files=ld, list_images=il, sub_pages=sp, sub_index_pages=spi, breadcrumbs=bc)
return fl
def load_lists_for_templates(self,path,is_index=True, cfg={}):
path2 = pjoin(FlatPagesIndex.FLATPAGES_ROOT,path)
if not is_index:
path="/".join(path2.split('/')[:-1])
# List all subpages of the current page
# get_sub_pages = partial(FlatPagesIndex.get_sub_pages, self)
# get_sub_ipages = partial(FlatPagesIndex.get_sub_ipages, self)
bc= self.breadcrumbs(path)
il=[]
if (cfg.get("has_img",False) ):
print "path2: %s" % path2
il=list_dir_img(mpath)
if is_index == True:
ld=list_dir_md(path2)
il=list_dir_img(path2)
sp=list(get_sub_pages(path))
spi=list(get_sub_ipages(path))
sp=self.get_sub_pages(path)
spi=self.get_sub_ipages(path)
else:
ld=[]
sp=[]
spi=[]
il=[]
bc=get_bc(path)
return (ld, il, sp, spi,bc)
fl=FileLists(list_files=ld, list_images=il, sub_pages=sp, sub_index_pages=spi, breadcrumbs=bc)
return fl

View File

@@ -0,0 +1,3 @@
!.eslintrc.js
js/*.min.js
js/vendor

View File

@@ -0,0 +1,7 @@
module.exports = {
extends: 'standard',
plugins: [
'standard',
'promise'
]
}

2
static/gallery/.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
.DS_Store
node_modules

View File

@@ -0,0 +1,8 @@
*
!css/*.css
!css/*.css.map
!img/*.gif
!img/*.png
!img/*.svg
!js/*.js
!js/*.js.map

View File

@@ -0,0 +1,22 @@
Copyright (C) 2013, 2016 Sebastian Tschan, https://blueimp.net
The Swipe implementation is based on https://github.com/bradbirdsall/Swipe,
licensed also under the MIT license.
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.

1095
static/gallery/README.md Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,71 @@
@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;
}
.blueimp-gallery > .indicator > li {
display: inline-block;
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;
}
.blueimp-gallery > .indicator > li:hover,
.blueimp-gallery > .indicator > .active {
background-color: #fff;
border-color: #fff;
opacity: 1;
}
.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;
}
.blueimp-gallery > .indicator {
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
/* IE7 fixes */
*+html .blueimp-gallery > .indicator > li {
display: inline;
}

View File

@@ -0,0 +1,87 @@
@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 > img {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
margin: auto;
width: auto;
height: auto;
max-width: 100%;
max-height: 100%;
/* Prevent artifacts in Mozilla Firefox: */
-moz-backface-visibility: hidden;
}
.blueimp-gallery > .slides > .slide > .video-content > video {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.blueimp-gallery > .slides > .slide > .video-content > iframe {
position: absolute;
top: 100%;
left: 0;
width: 100%;
height: 100%;
border: none;
}
.blueimp-gallery > .slides > .slide > .video-playing > iframe {
top: 0;
}
.blueimp-gallery > .slides > .slide > .video-content > a {
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 > .slides > .slide > .video-content > a:hover {
opacity: 1;
}
.blueimp-gallery > .slides > .slide > .video-playing > a,
.blueimp-gallery > .slides > .slide > .video-playing > img {
display: none;
}
.blueimp-gallery > .slides > .slide > .video-content > video {
display: none;
}
.blueimp-gallery > .slides > .slide > .video-playing > video {
display: block;
}
.blueimp-gallery > .slides > .slide > .video-loading > a {
background: url(../img/loading.gif) center no-repeat;
background-size: 64px 64px;
}
/* Replace PNGs with SVGs for capable browsers (excluding IE<9) */
body:last-child .blueimp-gallery > .slides > .slide > .video-content:not(.video-loading) > a {
background-image: url(../img/video-play.svg);
}
/* IE7 fixes */
*+html .blueimp-gallery > .slides > .slide > .video-content {
height: 100%;
}
*+html .blueimp-gallery > .slides > .slide > .video-content > a {
left: 50%;
margin-left: -64px;
}

View File

@@ -0,0 +1,226 @@
@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 {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
/* Prevent artifacts in Mozilla Firefox: */
-moz-backface-visibility: hidden;
}
.blueimp-gallery > .slides > .slide > .slide-content {
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;
background: rgba(0, 0, 0, 0.9);
opacity: 0;
display: none;
direction: ltr;
-ms-touch-action: none;
touch-action: none;
}
.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 10px #000;
-ms-touch-action: pan-y;
touch-action: pan-y;
}
.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 {
position: relative;
float: left;
height: 100%;
text-align: center;
-webkit-transition-timing-function: cubic-bezier(0.645, 0.045, 0.355, 1.000);
-moz-transition-timing-function: cubic-bezier(0.645, 0.045, 0.355, 1.000);
-ms-transition-timing-function: cubic-bezier(0.645, 0.045, 0.355, 1.000);
-o-transition-timing-function: cubic-bezier(0.645, 0.045, 0.355, 1.000);
transition-timing-function: cubic-bezier(0.645, 0.045, 0.355, 1.000);
}
.blueimp-gallery,
.blueimp-gallery > .slides > .slide > .slide-content {
-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;
}
.blueimp-gallery > .slides > .slide-loading {
background: url(../img/loading.gif) center no-repeat;
background-size: 64px 64px;
}
.blueimp-gallery > .slides > .slide-loading > .slide-content {
opacity: 0;
}
.blueimp-gallery > .slides > .slide-error {
background: url(../img/error.png) center no-repeat;
}
.blueimp-gallery > .slides > .slide-error > .slide-content {
display: none;
}
.blueimp-gallery > .prev,
.blueimp-gallery > .next {
position: absolute;
top: 50%;
left: 15px;
width: 40px;
height: 40px;
margin-top: -23px;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
font-size: 60px;
font-weight: 100;
line-height: 30px;
color: #fff;
text-decoration: none;
text-shadow: 0 0 2px #000;
text-align: center;
background: #222;
background: rgba(0, 0, 0, 0.5);
-webkit-box-sizing: content-box;
-moz-box-sizing: content-box;
box-sizing: content-box;
border: 3px solid #fff;
-webkit-border-radius: 23px;
-moz-border-radius: 23px;
border-radius: 23px;
opacity: 0.5;
cursor: pointer;
display: none;
}
.blueimp-gallery > .next {
left: auto;
right: 15px;
}
.blueimp-gallery > .close,
.blueimp-gallery > .title {
position: absolute;
top: 15px;
left: 15px;
margin: 0 40px 0 0;
font-size: 20px;
line-height: 30px;
color: #fff;
text-shadow: 0 0 2px #000;
opacity: 0.8;
display: none;
}
.blueimp-gallery > .close {
padding: 15px;
right: 15px;
left: auto;
margin: -15px;
font-size: 30px;
text-decoration: none;
cursor: pointer;
}
.blueimp-gallery > .play-pause {
position: absolute;
right: 15px;
bottom: 15px;
width: 15px;
height: 15px;
background: url(../img/play-pause.png) 0 0 no-repeat;
cursor: pointer;
opacity: 0.5;
display: none;
}
.blueimp-gallery-playing > .play-pause {
background-position: -15px 0;
}
.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;
}
.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;
}
/* Replace PNGs with SVGs for capable browsers (excluding IE<9) */
body:last-child .blueimp-gallery > .slides > .slide-error {
background-image: url(../img/error.svg);
}
body:last-child .blueimp-gallery > .play-pause {
width: 20px;
height: 20px;
background-size: 40px 20px;
background-image: url(../img/play-pause.svg);
}
body:last-child .blueimp-gallery-playing > .play-pause {
background-position: -20px 0;
}
/* IE7 fixes */
*+html .blueimp-gallery > .slides > .slide {
min-height: 300px;
}
*+html .blueimp-gallery > .slides > .slide > .slide-content {
position: relative;
}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
{"version":3,"sources":["blueimp-gallery.css","blueimp-gallery-indicator.css","blueimp-gallery-video.css"],"names":[],"mappings":"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"}

View File

@@ -0,0 +1,51 @@
/*
* 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: 750px;
margin: 0 auto;
padding: 1em;
font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, sans-serif;
font-size: 1em;
line-height: 1.4em;
background: #222;
color: #fff;
-webkit-text-size-adjust: 100%;
-ms-text-size-adjust: 100%;
}
a {
color: orange;
text-decoration: none;
}
img {
border: 0;
vertical-align: middle;
}
h1 {
line-height: 1em;
}
h2,
.links {
text-align: center;
}
@media (min-width: 481px) {
.navigation {
list-style: none;
padding: 0;
}
.navigation li {
display: inline-block;
}
.navigation li:not(:first-child):before {
content: '| ';
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

View 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="red" stroke-width="7" fill="black" fill-opacity="0.2"/>
<rect x="28" y="7" width="8" height="50" fill="red" transform="rotate(45, 32, 32)"/>
</svg>

After

Width:  |  Height:  |  Size: 306 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 606 B

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="30" height="15">
<polygon points="2,1 2,14 13,7" stroke="black" stroke-width="1" fill="white"/>
<rect x="17" y="2" width="4" height="11" stroke="black" stroke-width="1" fill="white"/>
<rect x="24" y="2" width="4" height="11" stroke="black" stroke-width="1" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 382 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

View 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="white" stroke-width="7" fill="black" fill-opacity="0.2"/>
<polygon points="26,22 26,42 43,32" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 274 B

84
static/gallery/index.html Normal file
View File

@@ -0,0 +1,84 @@
<!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,chrome=1">
<![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.<br>
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 class="navigation">
<li><a href="https://github.com/blueimp/Gallery/tags">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>
<p><a href="https://github.com/blueimp/Gallery">blueimp Gallery</a> is based on <a href="http://swipejs.com/">Swipe</a>.</p>
<br>
<h2>Carousel image gallery</h2>
<!-- The Gallery as inline carousel, can be positioned anywhere on the page -->
<div id="blueimp-image-carousel" class="blueimp-gallery blueimp-gallery-carousel">
<div class="slides"></div>
<h3 class="title"></h3>
<a class="prev"></a>
<a class="next"></a>
<a class="play-pause"></a>
</div>
<br>
<h2>Carousel video gallery</h2>
<!-- The Gallery as inline carousel, can be positioned anywhere on the page -->
<div id="blueimp-video-carousel" class="blueimp-gallery blueimp-gallery-controls blueimp-gallery-carousel">
<div class="slides"></div>
<h3 class="title"></h3>
<a class="prev"></a>
<a class="next"></a>
<a class="play-pause"></a>
</div>
<br>
<h2>Lightbox image gallery</h2>
<!-- The container for the list of example images -->
<div id="links" class="links"></div>
<!-- The Gallery as lightbox dialog, should be a child element of the document body -->
<div id="blueimp-gallery" class="blueimp-gallery">
<div class="slides"></div>
<h3 class="title"></h3>
<a class="prev"></a>
<a class="next"></a>
<a class="close">×</a>
<a class="play-pause"></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

@@ -0,0 +1,84 @@
/*
* 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, window, document */
;(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'
$.extend(Gallery.prototype.options, {
// Defines if the gallery should open in fullscreen mode:
fullScreen: false
})
var initialize = Gallery.prototype.initialize
var close = Gallery.prototype.close
$.extend(Gallery.prototype, {
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

@@ -0,0 +1,145 @@
/*
* 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, window, document */
;(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'
$.extend(Gallery.prototype.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 = Gallery.prototype.initSlides
var addSlide = Gallery.prototype.addSlide
var resetSlides = Gallery.prototype.resetSlides
var handleClick = Gallery.prototype.handleClick
var handleSlide = Gallery.prototype.handleSlide
var handleClose = Gallery.prototype.handleClose
$.extend(Gallery.prototype, {
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
}
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 (index) {
handleSlide.call(this, index)
this.setActiveIndicator(index)
},
handleClose: function () {
if (this.activeIndicator) {
this.activeIndicator.removeClass(this.options.activeIndicatorClass)
}
handleClose.call(this)
}
})
return Gallery
})

View File

@@ -0,0 +1,166 @@
/*
* 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, window, document */
;(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'
$.extend(Gallery.prototype.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 list object property (or data attribute) for the video poster URL:
videoPosterProperty: 'poster',
// The list object property (or data attribute) for the video sources array:
videoSourcesProperty: 'sources'
})
var handleSlide = Gallery.prototype.handleSlide
$.extend(Gallery.prototype, {
handleSlide: function (index) {
handleSlide.call(this, index)
if (this.playingVideo) {
this.playingVideo.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 url = this.getItemProperty(obj, options.urlProperty)
var type = this.getItemProperty(obj, options.typeProperty)
var title = this.getItemProperty(obj, options.titleProperty)
var posterUrl = this.getItemProperty(obj, options.videoPosterProperty)
var posterImage
var sources = this.getItemProperty(obj, options.videoSourcesProperty)
var source
var playMediaControl
var isLoading
var hasControls
videoContainer.addClass(options.videoContentClass)
if (title) {
videoContainerNode.title = title
}
if (video.canPlayType) {
if (url && type && video.canPlayType(type)) {
video.src = url
} else if (sources) {
while (sources.length) {
source = sources.shift()
url = this.getItemProperty(source, options.urlProperty)
type = this.getItemProperty(source, options.typeProperty)
if (url && type && video.canPlayType(type)) {
video.src = url
break
}
}
}
}
if (posterUrl) {
video.poster = posterUrl
posterImage = this.imagePrototype.cloneNode(false)
$(posterImage).addClass(options.toggleClass)
posterImage.src = posterUrl
posterImage.draggable = false
videoContainerNode.appendChild(posterImage)
}
playMediaControl = document.createElement('a')
playMediaControl.setAttribute('target', '_blank')
if (!videoInterface) {
playMediaControl.setAttribute('download', title)
}
playMediaControl.href = url
if (video.src) {
video.controls = true
;(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 (hasControls) {
that.container.addClass(that.options.controlsClass)
}
delete that.playingVideo
if (that.interval) {
that.play()
}
})
.on('playing', function () {
isLoading = false
videoContainer
.removeClass(that.options.videoLoadingClass)
.addClass(that.options.videoPlayingClass)
if (that.container.hasClass(that.options.controlsClass)) {
hasControls = true
that.container.removeClass(that.options.controlsClass)
} else {
hasControls = false
}
})
.on('play', function () {
window.clearTimeout(that.timeout)
isLoading = true
videoContainer.addClass(that.options.videoLoadingClass)
that.playingVideo = video
})
$(playMediaControl).on('click', function (event) {
that.preventDefault(event)
if (isLoading) {
video.pause()
} else {
video.play()
}
})
videoContainerNode.appendChild(
(videoInterface && videoInterface.element) || video
)
}
videoContainerNode.appendChild(playMediaControl)
this.setTimeout(callback, [
{
type: 'load',
target: videoContainerNode
}
])
return videoContainerNode
}
})
return Gallery
})

View File

@@ -0,0 +1,210 @@
/*
* 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, window, document, $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
}
$.extend(Gallery.prototype.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:
'//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: true
})
var textFactory =
Gallery.prototype.textFactory || Gallery.prototype.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, {
canPlayType: function () {
return true
},
on: function (type, func) {
this.listeners[type] = func
return this
},
loadAPI: function () {
var that = this
var apiUrl = '//f.vimeocdn.com/js/froogaloop2.min.js'
var scriptTags = document.getElementsByTagName('script')
var i = scriptTags.length
var scriptTag
var called
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
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(Gallery.prototype, {
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] = '//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

@@ -0,0 +1,223 @@
/*
* 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, window, document, 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
}
$.extend(Gallery.prototype.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: true
})
var textFactory =
Gallery.prototype.textFactory || Gallery.prototype.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, {
canPlayType: function () {
return true
},
on: function (type, func) {
this.listeners[type] = func
return this
},
loadAPI: function () {
var that = this
var onYouTubeIframeAPIReady = window.onYouTubeIframeAPIReady
var apiUrl = '//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 () {
Gallery.prototype.setTimeout.call(this, this.checkSeek, null, 2000)
},
checkSeek: function () {
if (
this.stateChange === YT.PlayerState.PAUSED ||
this.stateChange === YT.PlayerState.ENDED
) {
// check if current state change is actually paused
this.listeners.pause()
delete this.playStatus
}
},
onStateChange: function (event) {
switch (event.data) {
case YT.PlayerState.PLAYING:
this.hasPlayed = true
this.onPlaying()
break
case YT.PlayerState.PAUSED:
case YT.PlayerState.ENDED:
this.onPause()
break
}
// Save most recent state change to this.stateChange
this.stateChange = event.data
},
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(Gallery.prototype, {
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] = '//www.youtube.com/watch?v=' + videoId
}
if (
this.getItemProperty(obj, options.videoPosterProperty) === undefined
) {
obj[options.videoPosterProperty] =
'//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 it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,190 @@
/*
* 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, window, document */
;(function () {
'use strict'
function extend (obj1, obj2) {
var prop
for (prop in obj2) {
if (obj2.hasOwnProperty(prop)) {
obj1[prop] = obj2[prop]
}
}
return obj1
}
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 window.JSON && 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 element
while (i) {
i -= 1
element = this[i]
if (!element.className) {
element.className = className
return this
}
if (this.hasClass(className)) {
return this
}
element.className += ' ' + className
}
return this
},
removeClass: function (className) {
var regexp = new RegExp('(^|\\s+)' + className + '(\\s+|$)')
var i = this.length
var element
while (i) {
i -= 1
element = this[i]
element.className = element.className.replace(regexp, ' ')
}
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

@@ -0,0 +1,93 @@
/*
* 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'
// Load demo images from flickr:
$.ajax({
url: 'https://api.flickr.com/services/rest/',
data: {
format: 'json',
method: 'flickr.interestingness.getList',
api_key: '7617adae70159d09ba78cfec73c13be3' // jshint ignore:line
},
dataType: 'jsonp',
jsonp: 'jsoncallback'
}).done(function (result) {
var carouselLinks = []
var linksContainer = $('#links')
var baseUrl
// Add the demo images as links with thumbnails to the page:
$.each(result.photos.photo, function (index, photo) {
baseUrl = 'https://farm' + photo.farm + '.static.flickr.com/' +
photo.server + '/' + photo.id + '_' + photo.secret
$('<a/>')
.append($('<img>').prop('src', baseUrl + '_s.jpg'))
.prop('href', baseUrl + '_b.jpg')
.prop('title', photo.title)
.attr('data-gallery', '')
.appendTo(linksContainer)
carouselLinks.push({
href: baseUrl + '_c.jpg',
title: photo.title
})
})
// Initialize the Gallery as image carousel:
blueimp.Gallery(carouselLinks, {
container: '#blueimp-image-carousel',
carousel: true
})
})
// Initialize the Gallery as video carousel:
blueimp.Gallery([
{
title: 'Sintel',
href: 'https://archive.org/download/Sintel/' +
'sintel-2048-surround.mp4',
type: 'video/mp4',
poster: 'https://i.imgur.com/MUSw4Zu.jpg'
},
{
title: 'Big Buck Bunny',
href: 'https://upload.wikimedia.org/wikipedia/commons/c/c0/' +
'Big_Buck_Bunny_4K.webm',
type: 'video/webm',
poster: 'https://upload.wikimedia.org/wikipedia/commons/thumb/c/c0/' +
'Big_Buck_Bunny_4K.webm/4000px--Big_Buck_Bunny_4K.webm.jpg'
},
{
title: 'Elephants Dream',
href: 'https://upload.wikimedia.org/wikipedia/commons/8/83/' +
'Elephants_Dream_%28high_quality%29.ogv',
type: 'video/ogg',
poster: 'https://upload.wikimedia.org/wikipedia/commons/thumb/9/90/' +
'Elephants_Dream_s1_proog.jpg/800px-Elephants_Dream_s1_proog.jpg'
},
{
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
})
})

View File

@@ -0,0 +1,73 @@
/*
* 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, window, document */
;(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 = $('[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

10351
static/gallery/js/vendor/jquery.js vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,58 @@
{
"name": "blueimp-gallery",
"version": "2.27.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.1.6",
"eslint": "^4.5.0",
"eslint-config-standard": "^10.2.1",
"eslint-plugin-import": "^2.7.0",
"eslint-plugin-node": "^5.1.1",
"eslint-plugin-promise": "^3.5.0",
"eslint-plugin-standard": "^3.0.1",
"prettier-eslint-cli": "^4.2.1",
"uglify-js": "^3.0.28"
},
"scripts": {
"format": "prettier-eslint --no-semi --single-quote --write **/*.js",
"test": "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 -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 -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"
},
"main": "js/blueimp-gallery.js"
}

View File

@@ -1,15 +1,20 @@
{% extends "layout.html" %}
{% block content %}
<LINK href="{{ url_for('static', filename='gallery/css/blueimp-gallery.min.css')}}" rel="stylesheet" type="text/css">
<link rel="stylesheet" href="/Gallery/css/blueimp-gallery.min.css">
<script src="/Gallery/js/blueimp-gallery.min.js"></script>
<script src="{{ url_for('static', filename='gallery/js/blueimp-gallery.min.js')}}"></script>
<style>
#links a {
margin-left: -2px;
margin-right:-2px;
}
</style>
<div id="blueimp-gallery" class="blueimp-gallery">
</style>
<h1>{{post.title}}</h1>
{{ post.html|safe }}
<div id="blueimp-gallery" class="blueimp-gallery">
<div class="slides"></div>
<h3 class="title"></h3>
<a class="prev"></a>
@@ -19,11 +24,10 @@
<ol class="indicator"></ol>
</div>
<h1>{{post.title}}</h1>
<div id="links">
{% for d in il %}
<a href="/{{pth}}/{{d}}">
<img src="/{{pth}}/{{d}}" width="80" height="80" alt="">
{% for d in filelists.image_list %}
<a href="{{d.url}}">
<img src="{{d.url}}" width="80" height="80" alt="">
</a>
{% endfor %}
</div>

View File

@@ -7,8 +7,8 @@
<div class="row">
<div class="col-12">
<nav class="breadcrumb" style="background-color: #FFF">
{% for b in pagebreadcrumbs %}
<a href="{{url_for('page',name=b.path)}}" class="breadcrumb-item">{{b.title}} </a>
{% for b in filelists.breadcrumbs %}
<a href="{#url_for('page',name=b.path)#}{{b.url}}" class="breadcrumb-item">{{b.title}} </a>
{% endfor %}
<a href="{{url_for('page',name=post.path)}}" class="breadcrumb-item active">{{post.title}} </a>
</nav>

View File

@@ -4,15 +4,14 @@
<h1>{{post.title}}</h1>
{{post.date}}
{% if spi | length > 0 %}
{% if filelists.sub_index_pages | length > 0 %}
<hr/>
<b id="up_head"> Unterseiten: </b>
<ul class="nav flex-column flex-sm-row " labeledby="up_head">
{% for d in spi %}
{% for d in filelists.sub_index_pages %}
<li class="nav-item">
<a href="{{url_for('page',name=d['path'])}}" class="nav-link">
<h6> {{d.title}} <small class="text-muted">{{'/'.join(d.path.split('/')[-2:-1])}} </small>
</h6>
<a href="{{d.url}}" class="nav-link">
<h6> {{d.title}} <small class="text-muted">{{d.desc}} </small> </h6>
</a>
</li>
{% endfor %}
@@ -23,28 +22,32 @@
{{ post.html|safe }}
{% if sp|length > 0 %}
{% if filelists.sub_pages |length > 0 %}
<ul class="nav flex-column flex-sm-row" labeledby="inf_head">
{% for d in sp %}
<li class="nav-item">
<a href="{{url_for('page',name=d['path'])}}" class="nav-link text-info">
<h6> {{d.title}} <small class="text-muted">{{d.path.split('/')[-1]}} </small>
</h6>
{% for d in filelists.sub_pages %}
<li class="nav-item">
<a href="{{d.url}}" class="nav-link text-info">
<h6> {{d.title}} <small class="text-muted">{{d.desc}} </small>
</h6>
</a>
</li>
</li>
{% endfor %}
</ul>
{% endif %}
{% if filelists.list_files |length > 0 %}
<hr/>
<b id="inf_head">Files:</b>
<ul>
{% for d in ld %}
<li>
<a href="{{url_for('page', name=d)}}">{{d}} </a>
</li>
{% for d in filelists.list_files %}
<li>
<a href="{{d.url}}">{{d}} </a>
</li>
{% endfor %}
</ul>
{% endif %}
{% endblock %}

10
test_flatpages.py Normal file
View File

@@ -0,0 +1,10 @@
import unittest
import flatpages as fp
from mock import patch
class TestFlatpages(unittest.TestCase):
def test_p(self):
self.assertEquals(fp.FlatPagesIndex.get_breadcrumb_paths(""),['index'])
self.assertEquals(fp.FlatPagesIndex.get_breadcrumb_paths("index"),['index'])
if __name__ == '__main__':
unittest.main()

View File

@@ -5,6 +5,8 @@ import os
import re
from os.path import isfile, abspath
from collections import namedtuple
LinkElement=namedtuple("LinkElement", ["title", "url","desc"])
def pjoin2 (pth):
if (not type(pth) is list):
@@ -32,3 +34,18 @@ def path_depth(path):
if p_split[-1]=='index' or p_split[-1]=='index.json' :
cc=cc-1
return cc
def page_to_link(pages, url_for_method):
"page to url"
for p in pages:
yield LinkElement(title=p.meta.get("title",p.path),
url=url_for_method(name=p.path),
desc='/'.join(p.path.split('/')[-2:-1])
)
def file_to_link(files, url_for_method):
"file to url"
for p in files:
yield LinkElement(title=p,
url=url_for_method(name=p),
desc=""
)