Code working but some features missing and glitches

This commit is contained in:
Kujiu 2021-06-02 03:23:50 +02:00
parent adaa36dcf0
commit ebfbd3b6fc
Signed by: kujiu
GPG key ID: ABBB2CAC6855599F
8 changed files with 772 additions and 101 deletions

View file

@ -1,7 +1,8 @@
sphinx_galleria sphinx_galleria
############### ###############
Create image galleries with Sphinx. Create image galleries with Sphinx. No external JS
dependency.
Install Install
~~~~~~~ ~~~~~~~
@ -12,6 +13,11 @@ If you're using a virtualenv, just:
pip install sphinx-galleria pip install sphinx-galleria
.. important::
Your webserver must deliver .mjs file with correct
content type (`application/javascript`).
Using Using
~~~~~ ~~~~~
@ -23,24 +29,30 @@ Just use the galleria directive like this:
.. code:: rst .. code:: rst
.. galleria:: imagefile1 imagefile2 images*.jpg .. galleria:: imagefile1 imagefile2 images*.jpg
:galleria: (optional) Name of gallery :galleria: (optional) Name of gallery - node level
:description: (optional) A long description :alt: (optional) A long description - image level
:title: (optional) Title of image :title: (optional) Title of image - image level
:thumbsize: (optional) Image size (defaults to "100x100") :thumbsize: (optional) Image size (defaults to "100x100") - image level
:transition: (optional, once) Transition for gallery :width: Width of image (in pixel or percentage or with unit, default auto) - node level
:theme: (optional, once) Theme name for galleria :height: (optional) Height of image (in pixel or with unit) - node level
:class: (optional, once) HTML class for gallery :align: Align to 'right', 'left' or 'center' (default to center) - node level
:hide_title: Flag - hide title under image (not in dialog) - image level
:hide_alt: Flag - hide alternative text under image - image level
:transition: (optional, once) Transition for gallery - image level
:class: (optional, once) HTML class for gallery - node level
Title, thumbnail size and description are same for all Image level options are same for all images defined by
images defined by the directive. If you need separated the directive. If you need separated descriptions and
descriptions and titles, just use the directive several titles, just use the directive several times with the
times with the same galleria name. In this case, theme same galleria name. In this case, node level options
html class and transition must be defined only in must be defined only once.
one directive.
Thumbnail size is in "WIDTHxHEIGHT" format, resulting Thumbnail size is in "WIDTHxHEIGHT" format, resulting
image keeps ratio. image keeps ratio.
The first image of a gallery is displayed if javascript
is not available on the browser.
Licensing Licensing
~~~~~~~~~ ~~~~~~~~~

View file

@ -17,7 +17,7 @@ setup(
package_data={ package_data={
"sphinx_galleria": [ "sphinx_galleria": [
"*.py", "*.py",
"static/sphinxgalleria/*.js", "static/sphinxgalleria/*.mjs",
"static/sphinxgalleria/*.css", "static/sphinxgalleria/*.css",
] ]
}, },

View file

@ -2,7 +2,7 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
""" """
Create image galleries with GalleriaJS Create image galleries
""" """
import os import os
from typing import Dict, Any from typing import Dict, Any
@ -39,8 +39,28 @@ def copy_images_files(app: Sphinx, env: BuildEnvironment) -> None:
ensuredir(os.path.dirname(dest)) ensuredir(os.path.dirname(dest))
with Image.open(original) as im: with Image.open(original) as im:
im.thumbnail(thumbsize) if im.size[0]/im.size[1] > thumbsize[0]/thumbsize[1]:
im.save(dest, "JPEG") out = im.resize((
thumbsize[0],
thumbsize[1]
), box=(
(im.size[0]-thumbsize[1]*im.size[0]/thumbsize[0])//2,
0,
(im.size[0]+thumbsize[1]*im.size[0]/thumbsize[0])//2,
im.size[1]
))
else:
out = im.resize((
thumbsize[0],
thumbsize[1]
), box=(
0,
(im.size[1]-thumbsize[0]*im.size[1]/thumbsize[0])//2,
im.size[0],
(im.size[1]+thumbsize[0]*im.size[1]/thumbsize[0])//2,
))
out.save(dest, "JPEG")
def install_static_files(app: Sphinx, env: BuildEnvironment) -> None: def install_static_files(app: Sphinx, env: BuildEnvironment) -> None:
@ -69,12 +89,16 @@ def install_static_files(app: Sphinx, env: BuildEnvironment) -> None:
copyfile(source_path, static_path) copyfile(source_path, static_path)
if static.endswith('.js'): if static.endswith('.css'):
app.add_js_file(os.path.join('sphinxgalleria', static))
elif static.endswith('.css'):
app.add_css_file(os.path.join('sphinxgalleria', static)) app.add_css_file(os.path.join('sphinxgalleria', static))
def init_directive(app: Sphinx, config) -> None:
if 'galleria_override_image' in config and \
config['galleria_override_image']:
app.add_directive('image', directive.GalleriaDirective)
def setup(app: Sphinx) -> Dict[str, Any]: def setup(app: Sphinx) -> Dict[str, Any]:
app.add_node( app.add_node(
directive.galleria, directive.galleria,
@ -88,6 +112,8 @@ def setup(app: Sphinx) -> Dict[str, Any]:
) )
app.add_directive('galleria', directive.GalleriaDirective) app.add_directive('galleria', directive.GalleriaDirective)
app.add_env_collector(collector.GalleriaCollector) app.add_env_collector(collector.GalleriaCollector)
app.add_config_value('galleria_override_image', False, 'boolean')
app.connect('env-updated', install_static_files) app.connect('env-updated', install_static_files)
app.connect('env-updated', copy_images_files) app.connect('env-updated', copy_images_files)
app.connect('config-inited', init_directive)
return {'version': __version__} return {'version': __version__}

View file

@ -84,7 +84,7 @@ class GalleriaCollector(EnvironmentCollector):
images.append({ images.append({
'title': imageglob['title'], 'title': imageglob['title'],
'description': imageglob['description'], 'alt': imageglob['alt'],
'thumb': os.path.relpath( 'thumb': os.path.relpath(
thumb_path_jpg, thumb_path_jpg,
app.env.srcdir), app.env.srcdir),

View file

@ -17,6 +17,8 @@ from sphinx.writers.latex import LaTeXTranslator
from sphinx.writers.texinfo import TexinfoTranslator from sphinx.writers.texinfo import TexinfoTranslator
from sphinx.writers.text import TextTranslator from sphinx.writers.text import TextTranslator
from sphinx.writers.manpage import ManualPageTranslator from sphinx.writers.manpage import ManualPageTranslator
from sphinx.util.osutil import relative_uri
from sphinx.locale import __
class galleria(nodes.General, nodes.Element): class galleria(nodes.General, nodes.Element):
@ -27,15 +29,30 @@ def html_visit_galleria(self: HTMLTranslator, node: galleria) -> None:
galleria_id = 'galleria-%s' % uuid.uuid4() galleria_id = 'galleria-%s' % uuid.uuid4()
self.body.append( self.body.append(
"<div id='%s' class='%s'></div>" % ( "<div id='%s' class='%s' width='%s' height='%s'>" % (
galleria_id, galleria_id,
node['class'] node['class'] + ' align-%s' % node['options']['align'],
node['options']['width'],
node['options']['height'],
) )
) )
if len(node['images']) > 0:
self.body.append("<figure><div class='row'>")
self.body.append("<img src='%s' title='%s' alt='%s'>" % (
node['images'][0]['image'],
node['images'][0]['title'],
node['images'][0]['alt']
))
self.body.append('</div></figure>')
self.body.append( self.body.append(
"<script>document.addEventListener('ready', function() {" + "</div><script type='module'>" +
"SphinxGalleria.run('%s', %s, dataSource=%s).init()});</script>" % ( "import {SphinxGalleria} from './%s';\n" %
relative_uri(
self.builder.get_target_uri(self.builder.current_docname),
'_static/sphinxgalleria/sphinxgalleria.mjs') +
"new SphinxGalleria('%s', %s, %s).init();</script>" % (
galleria_id, galleria_id,
json.dumps(node['options']), json.dumps(node['options']),
json.dumps(node['images']) json.dumps(node['images'])
@ -47,66 +64,84 @@ def html_visit_galleria(self: HTMLTranslator, node: galleria) -> None:
def latex_visit_galleria(self: LaTeXTranslator, node: galleria) -> None: def latex_visit_galleria(self: LaTeXTranslator, node: galleria) -> None:
for image in node['images']: for image in node['images']:
self.body.append('[%s]' % image['description']) self.body.append('[%s]' % image['alt'])
raise nodes.SkipNode raise nodes.SkipNode
def texinfo_visit_galleria(self: TexinfoTranslator, node: galleria) -> None: def texinfo_visit_galleria(self: TexinfoTranslator, node: galleria) -> None:
for image in node['images']: for image in node['images']:
self.body.append('[%s]' % image['description']) self.body.append('[%s]' % image['alt'])
raise nodes.SkipNode raise nodes.SkipNode
def text_visit_galleria(self: TextTranslator, node: galleria) -> None: def text_visit_galleria(self: TextTranslator, node: galleria) -> None:
for image in node['images']: for image in node['images']:
self.body.append('[%s]' % image['description']) self.body.append('[%s]' % image['alt'])
raise nodes.SkipNode raise nodes.SkipNode
def gemini_visit_galleria(self, node: galleria) -> None: def gemini_visit_galleria(self, node: galleria) -> None:
for image in node['images']: for image in node['images']:
self.body.append('=> %s %s' % (image['path'], image['description'])) self.body.append('=> %s %s' % (image['path'], image['alt']))
raise nodes.SkipNode raise nodes.SkipNode
def man_visit_galleria(self: ManualPageTranslator, node: galleria) -> None: def man_visit_galleria(self: ManualPageTranslator, node: galleria) -> None:
if 'description' in node.attributes: if 'alt' in node.attributes:
self.body.append('[%s]' % node['description']) self.body.append('[%s]' % node['alt'])
raise nodes.SkipNode raise nodes.SkipNode
def align_choices(argument):
return directives.choice(argument, ('left', 'right', 'center'))
class GalleriaDirective(Directive): class GalleriaDirective(Directive):
has_content = False has_content = False
required_arguments = 1 required_arguments = 1
final_argument_whitespace = True final_argument_whitespace = True
option_spec = { option_spec = {
"class": directives.unchanged, "class": directives.class_option,
"galleria": directives.unchanged, "galleria": directives.unchanged,
"description": directives.unchanged, "alt": directives.unchanged,
"title": directives.unchanged, "title": directives.unchanged,
"thumbsize": directives.unchanged, "thumbsize": directives.unchanged,
"transition": directives.unchanged, "transition": directives.unchanged,
'width': directives.length_or_percentage_or_unitless,
'height': directives.length_or_unitless,
'align': align_choices,
'hide_title': directives.flag,
'hide_alt': directives.flag,
} }
def run(self): def run(self):
if not self.state.document.hasattr('galleria_nodes'): source = self.state.document.settings._source
self.state.document.galleria_nodes = {} document = self.state.document
if not document.hasattr('galleria_nodes'):
document.galleria_nodes = {}
if source not in document.galleria_nodes:
document.galleria_nodes[source] = {}
galleria_name = self.options.get('galleria') galleria_name = self.options.get('galleria') or uuid.uuid4()
created = False created = False
if galleria_name and \ if galleria_name in document.galleria_nodes[source]:
galleria_name in self.state.document.galleria_nodes: node = document.galleria_nodes[source][galleria_name]
node = self.state.document.galleria_nodes[galleria_name]
else: else:
node = galleria() node = galleria()
node['class'] = 'galleria' node['class'] = 'galleria'
node['options'] = { node['options'] = {
'transition': 'fade' 'transition': 'fade',
'label_prev': __('Previous'),
'label_next': __('Next'),
'label_close': __('Close'),
'label_thumbnail': __('Thumbnail, click to enlarge'),
} }
node['images'] = [] node['images'] = []
document.galleria_nodes[source][galleria_name] = node
created = True created = True
@ -115,12 +150,18 @@ class GalleriaDirective(Directive):
if self.options.get('transition'): if self.options.get('transition'):
node['options']['transition'] = self.options['transition'] node['options']['transition'] = self.options['transition']
node['options']["width"] = self.options.get('width') or 'auto'
node['options']["height"] = self.options.get('height') or 'auto'
node['options']["align"] = self.options.get('align') or 'center'
images_path = self.arguments images_path = self.arguments
for path in images_path: for path in images_path:
image = {} image = {}
image["description"] = self.options.get('description') image["alt"] = self.options.get('alt')
image["title"] = self.options.get('title') image["title"] = self.options.get('title')
image["thumbsize"] = self.options.get('thumbsize') or '100x100' image["thumbsize"] = self.options.get('thumbsize') or '100x100'
image["hide_alt"] = bool(self.options.get('hide_alt'))
image["hide_title"] = bool(self.options.get('hide_title'))
image["image"] = path image["image"] = path
node['images'].append(image) node['images'].append(image)

View file

@ -0,0 +1,283 @@
.sphinxgalleria-core {
text-align: center;
}
.sphinxgalleria-core.align-center {
margin: auto;
}
.sphinxgalleria-core.align-left {
float: left;
}
.sphinxgalleria-core.align-right {
float: right;
}
.sphinxgalleria-core figure .row {
flex-flow: row nowrap;
display: flex;
}
.sphinxgalleria-core figure .row button {
flex-grow: 1;
flex-shrink: 1;
cursor: pointer;
}
.sphinxgalleria-core figure .row button.button-modal {
flex-grow: 1000;
flex-shrink: 1000;
margin: 0;
padding: 0;
border: none;
width: max-content;
height: max-content;
display: flex;
flex-flow: column nowrap;
}
.sphinxgalleria-core figure .row button.button-modal .caption {
background-color: hsl(0, 0%, 34%);
color: white;
text-transform: none;
border-bottom-left-radius: .5rem;
border-bottom-right-radius: .5rem;
border: none;
margin: 0;
padding: .5rem 1.5rem .5rem 1.5rem;
width: 100%;
text-align: left;
}
.sphinxgalleria-core figure .row button.button-modal figcaption {
font-style: italic;
text-align: center;
}
.sphinxgalleria-core figure .row button.button-modal img {
margin: 0;
padding: 0;
border: none;
width: auto;
height: auto;
object-fit: contain;
}
.sphinxgalleria-core figure input[type=range] {
width: 100%;
height: 1.5rem;
border: none;
-webkit-appearance: none;
}
.sphinxgalleria-core figure input[type=range]:focus {
outline: none;
border: none;
}
.sphinxgalleria-core figure input[type=range]::-webkit-slider-runnable-track {
width: 100%;
height: .1rem;
padding: 0 1rem 0 1rem;
margin: 0;
border: none;
cursor: pointer;
animate: 0.2s;
background-color: hsl(0, 0%, 34%);
}
.sphinxgalleria-core figure input[type=range]::-webkit-slider-thumb {
height: 1rem;
width: 1rem;
border-radius: .5rem;
border: none;
background-color: hsl(0, 0%, 34%);
cursor: pointer;
-webkit-appearance: none;
margin-top: -.5rem;
}
.sphinxgalleria-core figure input[type=range]:focus::-webkit-slider-runnable-track {
background-color: hsl(0, 0%, 34%);
border: none;
}
.sphinxgalleria-core figure input[type=range]::-moz-range-track {
width: 100%;
padding: 0 1rem 0 1rem;
margin: 0;
border: none;
height: .1rem;
cursor: pointer;
animate: 0.2s;
background-color: hsl(0, 0%, 34%);
}
.sphinxgalleria-core figure input[type=range]::-moz-range-thumb {
height: 1rem;
width: 1rem;
border-radius: .5rem;
background-color: hsl(0, 0%, 34%);
cursor: pointer;
}
.sphinxgalleria-core .mask {
position: fixed;
top: 0;
left: 0;
height: 100vh;
width: 100vw;
margin: 0;
padding: 0;
background-color: hsla(0, 0%, 0%, 80%);
z-index: 1000;
}
.sphinxgalleria-core .submask {
height: 100%;
width: 100%;
margin: 0;
padding: 0;
position: relative;
}
.sphinxgalleria-core dialog {
position: absolute;
top: 3vh;
left: 0;
height: 90vh;
max-height: 90vh;
width: max-content;
margin: 0 auto 0 auto;
padding-left: 3rem;
padding-right: 3rem;
background-color: black;
color: white;
border: white solid 0.2rem;
border-radius: 0.5rem;
text-align: center;
display: flex;
flex-flow: column nowrap;
}
.sphinxgalleria-core dialog img {
height: 100%;
width: auto;
object-fit: contain;
flex-grow: 1000;
flex-shrink: 1000;
margin: 0.5rem 0 0.5rem 0;
padding: 0;
}
.sphinxgalleria-core dialog menu {
text-align: left;
width: 100%;
padding: 0;
margin: 0;
}
.sphinxgalleria-core dialog button {
border: none;
padding: .5em;
background-color: black;
color: white;
}
.sphinxgalleria-core dialog button:hover,
.sphinxgalleria-core dialog button:focus {
background-color: hsl(0, 0%, 34%);
transition: background-color ease 0.4s;
}
.sphinxgalleria-core dialog header button {
position: absolute;
top: .5rem;
right: -.5rem;
}
.sphinxgalleria-core dialog header button::after {
content: '✕';
}
.sphinxgalleria-core dialog header {
position: relative;
min-height: 3rem;
}
.sphinxgalleria-core dialog menu {
height: 3rem;
}
.sphinxgalleria-core dialog header::after {
clear: both;
}
.sphinxgalleria-core dialog menu button.close {
float: right;
}
.sphinxgalleria-core dialog menu button.close::before {
margin-right: 0.5rem;
content: '✕';
}
.sphinxgalleria-core figure button.prev,
.sphinxgalleria-core figure button.next {
background-color: hsl(0, 0%, 34%);
color: white;
height: 4rem;
width: 4rem;
margin: auto .5rem auto .5rem;
border-radius: 1rem;
border: none;
}
.sphinxgalleria-core figure button.prev:hover,
.sphinxgalleria-core figure button.next:hover,
.sphinxgalleria-core figure button.prev:focus,
.sphinxgalleria-core figure button.next:focus {
background-color: hsl(0, 0%, 64%);
transition: background-color ease .4s;
}
.sphinxgalleria-core figure button.prev {
}
.sphinxgalleria-core figure button.next {
}
.sphinxgalleria-core figure button.prev::before,
.sphinxgalleria-core dialog menu button.prev::before {
margin-right: 0.5rem;
content: '←';
}
.sphinxgalleria-core figure button.next::after,
.sphinxgalleria-core dialog menu button.next::after {
margin-left: 0.5rem;
content: '→';
}
.sphinxgalleria-core ul.thumbnails {
overflow-x: hidden;
margin: 0 auto 0 auto;
padding: 0;
max-width: 100%;
height: max-content;
display: inline-flex;
flex-flow: row nowrap;
justify-content: flex-start;
}
.sphinxgalleria-core ul.thumbnails li {
list-style: none;
}
.sphinxgalleria-core ul.thumbnails li input[type=radio] {
display: none;
}
.sphinxgalleria-core ul.thumbnails li input:checked + label {
opacity: .5;
}
.sphinxgalleria-core ul.thumbnails li img {
margin: 0.5rem;
cursor: pointer;
max-width: unset;
}

View file

@ -1,59 +0,0 @@
"use strict";
class SphinxGalleria {
constructor(target, options, data) {
var self = this;
self.target = target;
self.options = options;
self.data = data;
self.node_target = null;
self.node_figure = document.createElement('figure');
self.node_image = document.createElement('img');
self.node_caption = document.createElement('figcaption');
self.node_thumbnails = document.createElement('div');
self.node_dialog = document.createElement('dialog', modal=true);
var button_prev = document.createElement('button', id=self.target+"-prev")
var button_next = document.createElement('button', id=self.target+"-next")
button_prev.appendChild(document.createTextNode('<'));
button_next.appendChild(document.createTextNode('>'));
button_prev.onkeypress = self.onprev
button_prev.onclick = self.onprev
button_next.onkeypress = self.onnext
button_.onclick = self.onnext
self.node_figure.appendChild(self.node_image);
self.node_figure.appendChild(button_prev);
self.node_figure.appendChild(button_next);
self.node_figure.appendChild(self.node_caption);
}
init() {
var self = this;
self.node_target = document.getElementById(self.target);
self.node_target.innerHTML = '';
self.node_target.appendChild(self.node_figure);
self.node_target.appendChild(self.node_thumbnails);
self.node_target.appendChild(self.node_dialog);
}
onprev(event) {
var key = event.keyCode || event.charCode || event.which;
if(event.type==='keypress' && key!==13 && key!==32) {
return
}
}
onnext(event) {
var key = event.keyCode || event.charCode || event.which;
if(event.type==='keypress' && key!==13 && key!==32) {
return
}
}
changeImage() {
}
}

View file

@ -0,0 +1,368 @@
"use strict()";
export class SphinxGalleria {
constructor(target, options, data) {
var self = this;
self.target = target;
self.options = options;
self.data = data;
self.oneimage = self.data.length === 1;
self.node_target = null;
self.node_figure = document.createElement('figure');
self.button_modal = document.createElement('button');
self.button_modal.setAttribute('aria-haspopup', 'dialog');
self.button_modal.setAttribute('class', 'button-modal');
self.node_image = document.createElement('img');
self.node_caption = document.createElement('figcaption');
self.node_alt = document.createElement('p');
self.node_alt.setAttribute('id', self.target+'-'+'alt');
self.node_image.setAttribute('aria-describedby', self.target+'-'+'alt');
self.node_thumbnails = document.createElement('ul');
self.node_thumbnails.setAttribute('class', 'thumbnails');
self.node_dialog = document.createElement('dialog');
self.node_mask = document.createElement('div');
self.node_mask.setAttribute('class', 'mask');
self.node_mask.hidden = true;
var node_submask = document.createElement('div');
node_submask.setAttribute('class', 'submask');
self.node_div_caption = document.createElement('div');
self.node_div_caption.setAttribute('class', 'caption');
var figure_row = document.createElement('div');
figure_row.setAttribute('class', 'row');
self.dialog_button_close = document.createElement('button');
self.dialog_button_close.setAttribute('class', 'close');
self.dialog_button_close_icon = document.createElement('button');
self.dialog_button_close_icon.setAttribute('aria-label', self.options.label_close);
self.dialog_image = document.createElement('img');
self.dialog_image.setAttribute('aria-describedby', self.target+'-'+'alt');
self.dialog_title = document.createElement('h1');
var dialog_header = document.createElement('header');
var dialog_menu = document.createElement('menu');
if(self.oneimage) {
self.node_thumbnails.hidden = true;
self.node_thumbnails.setAttribute('aria-hidden', true);
self.node_thumbnails.style.visibility = 'hidden';
} else {
self.node_slider = document.createElement('input');
self.node_slider.setAttribute('type', 'range');
self.node_slider.setAttribute('min', 1);
self.node_slider.setAttribute('max', self.data.length);
self.node_slider.setAttribute('value', 1);
self.button_prev = document.createElement('button');
self.button_prev.setAttribute('class', 'prev');
self.button_prev.setAttribute('aria-label', self.options.label_prev);
self.button_next = document.createElement('button');
self.button_next.setAttribute('class', 'next');
self.button_next.setAttribute('aria-label', self.options.label_next);
self.dialog_button_prev = document.createElement('button');
self.dialog_button_prev.setAttribute('class', 'prev');
self.dialog_button_next = document.createElement('button');
self.dialog_button_next.setAttribute('class', 'next');
self.dialog_button_prev.appendChild(document.createTextNode(self.options.label_prev));
self.dialog_button_next.appendChild(document.createTextNode(self.options.label_next));
figure_row.appendChild(self.button_prev);
dialog_menu.appendChild(self.dialog_button_prev);
dialog_menu.appendChild(self.dialog_button_next);
}
node_submask.appendChild(self.node_dialog);
self.node_mask.appendChild(node_submask);
figure_row.appendChild(self.button_modal);
self.node_figure.appendChild(figure_row);
self.node_div_caption.appendChild(self.node_caption);
self.node_div_caption.appendChild(self.node_alt);
self.button_modal.appendChild(self.node_image);
self.button_modal.appendChild(self.node_div_caption);
self.dialog_button_close.appendChild(document.createTextNode(self.options.label_close));
dialog_header.appendChild(self.dialog_title);
dialog_header.appendChild(self.dialog_button_close_icon);
self.node_dialog.appendChild(dialog_header);
self.node_dialog.appendChild(self.dialog_image);
dialog_menu.appendChild(self.dialog_button_close);
self.node_dialog.appendChild(dialog_menu);
if(!self.oneimage) {
figure_row.appendChild(self.button_next);
self.node_figure.appendChild(self.node_slider);
}
}
init() {
var self = this;
self.node_target = document.getElementById(self.target);
self.node_target.innerHTML = '';
self.node_target.setAttribute(
'class',
self.node_target.getAttribute('class') + " sphinxgalleria-core"
);
self.node_target.appendChild(self.node_figure);
self.node_target.appendChild(self.node_thumbnails);
self.node_target.appendChild(self.node_mask);
var onmodal = function(event) {
var key = event.keyCode || event.charCode || event.which;
if(event.type==='keypress' && key!==13 && key!==32) {
return;
}
event.preventDefault();
self.showModal();
};
self.button_modal.addEventListener('click', onmodal);
self.button_modal.addEventListener('keypress', onmodal);
var onclose = function(event) {
var key = event.keyCode || event.charCode || event.which;
if(event.type==='keypress' && key!==13 && key!==32) {
return;
}
event.preventDefault();
self.closeModal();
};
self.node_mask.addEventListener('click', onclose);
self.node_dialog.addEventListener('click', function(e) {e.stopPropagation();});
self.dialog_button_close.addEventListener('click', onclose);
self.dialog_button_close.addEventListener('keypress', onclose);
self.dialog_button_close_icon.addEventListener('click', onclose);
self.dialog_button_close_icon.addEventListener('keypress', onclose);
if(!self.oneimage) {
var onprev = function(event) {
var key = event.keyCode || event.charCode || event.which;
if(event.type==='keypress' && key!==13 && key!==32) {
return;
}
event.preventDefault();
self.prev();
};
var onnext = function(event) {
var key = event.keyCode || event.charCode || event.which;
if(event.type==='keypress' && key!==13 && key!==32) {
return;
}
event.preventDefault();
self.next();
};
self.button_prev.addEventListener('keypress', onprev);
self.button_prev.addEventListener('click', onprev);
self.button_next.addEventListener('keypress', onnext);
self.button_next.addEventListener('click', onnext);
self.dialog_button_prev.addEventListener('keypress', onprev);
self.dialog_button_prev.addEventListener('click', onprev);
self.dialog_button_next.addEventListener('keypress', onnext);
self.dialog_button_next.addEventListener('click', onnext);
self.dialog_image.addEventListener('click', function(e) {
var x = e.layerX - e.target.x;
if(x < e.target.width/2) {
self.prev();
e.preventDefault();
} else if(x > e.target.width/2) {
self.next();
e.preventDefault();
}
});
self.node_slider.addEventListener('change', function() {
var idx = self.node_slider.value - 1;
self.node_thumbnails.querySelector('input[data-index="'+idx+'"]').click();
});
}
self.data.forEach(function(image_data, idx) {
var image_element = document.createElement('li');
var image_button = document.createElement('input');
image_button.setAttribute('type', 'radio');
image_button.setAttribute('value', image_data.image);
image_button.setAttribute('name', self.target);
image_button.setAttribute('data-index', idx);
image_button.setAttribute('id', self.target+'-'+idx);
if(idx===0) {
image_button.checked = true;
}
image_element.appendChild(image_button);
var image_label = document.createElement('label');
image_label.setAttribute('for', self.target+'-'+idx);
image_element.appendChild(image_label);
var image_thumb = document.createElement('img');
image_thumb.setAttribute('src', image_data.thumb);
if(image_data.alt) {
image_button.setAttribute('data-alt', image_data.alt);
image_thumb.setAttribute('alt', image_data.alt);
} else {
image_thumb.setAttribute('alt', self.options.label_thumbnail);
}
if(image_data.title) {
image_button.setAttribute('data-title', image_data.title);
}
if(image_data.hide_alt) {
image_button.setAttribute('data-hide-alt', true);
}
if(image_data.hide_alt) {
image_button.setAttribute('data-hide-title', true);
}
if(image_data.transition) {
image_thumb.setAttribute('data-transition', image_data.transition);
}
image_label.appendChild(image_thumb);
self.node_thumbnails.appendChild(image_element);
image_button.addEventListener('change', function() {self.changeImage();});
});
self.node_target.addEventListener('keypress', function(event) {
var key = event.keyCode || event.charCode || event.which;
if(!self.oneimage && key===37) {
self.prev();
} else if(!self.oneimage && key===39) {
self.next();
} else if(key===27) {
self.closeModal();
}
});
self.changeImage();
}
prev() {
var self = this;
if(!self.oneimage) {
var idx = self.node_thumbnails.querySelector('input:checked').getAttribute('data-index');
idx = parseInt(idx) - 1;
if(idx < 0) {
idx = self.data.length - 1;
}
document.getElementById(self.target+'-'+idx).checked = true;
self.changeImage();
}
}
next() {
var self = this;
if(!self.oneimage) {
var idx = self.node_thumbnails.querySelector('input:checked').getAttribute('data-index');
idx = parseInt(idx) + 1;
if(idx > self.data.length - 1) {
idx = 0;
}
document.getElementById(self.target+'-'+idx).checked = true;
self.changeImage();
}
}
changeImage() {
var self = this;
var current = self.node_thumbnails.querySelector('input:checked');
var title = current.getAttribute('data-title');
var alt = current.getAttribute('data-alt');
var hide_title = current.hasAttribute('data-hide-title');
var hide_alt = current.hasAttribute('data-hide-alt');
var url = current.getAttribute('value');
var hide_caption = true;
var idx = parseInt(current.getAttribute('data-index'));
if(!self.oneimage) {
if(self.node_slider.value !== idx+1) {
self.node_slider.value = idx + 1;
}
var current_img = current.nextSibling.childNodes[0];
self.node_thumbnails.scrollTo({
left: current_img.x -
self.node_thumbnails.offsetWidth/2 +
current_img.clientWidth/2,
top: 0,
behavior: 'smooth'
});
}
if(!hide_title && title) {
self.node_caption.innerHTML = title;
self.node_caption.hidden = false;
self.dialog_title.innerHTML = title;
self.dialog_title.hidden = false;
hide_caption = false;
} else if(title) {
self.node_caption.innerHTML = '';
self.node_caption.hidden = true;
self.dialog_title.innerHTML = title;
self.dialog_title.hidden = false;
} else {
self.node_caption.innerHTML = '';
self.node_caption.hidden = true;
self.dialog_title.innerHTML = '';
self.dialog_title.hidden = true;
}
if(!hide_alt && alt) {
self.node_alt.innerHTML = alt;
self.node_alt.hidden = false;
hide_caption = false;
} else {
self.node_alt.innerHTML = '';
self.node_alt.hidden = true;
}
if(hide_caption) {
self.node_div_caption.hidden = true;
} else {
self.node_div_caption.hidden = false;
}
self.node_image.setAttribute('src', url);
self.dialog_image.setAttribute('src', url);
}
showModal() {
this.node_mask.hidden = false;
if(this.node_dialog.showModal) {
this.node_dialog.showModal();
} else {
this.node_dialog.open = true;
this.node_dialog.setAttribute('open', true);
this.node_dialog.setAttribute('aria-modal', true);
this.node_dialog.hidden = false;
}
}
closeModal() {
if(this.node_dialog.showModal) {
this.node_dialog.close();
} else {
this.node_dialog.open = false;
this.node_dialog.removeAttribute('open');
this.node_dialog.removeAttribute('aria-modal');
this.node_dialog.hidden = true;
}
this.node_mask.hidden = true;
}
}