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

View file

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

View file

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

View file

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

View file

@ -17,6 +17,8 @@ from sphinx.writers.latex import LaTeXTranslator
from sphinx.writers.texinfo import TexinfoTranslator
from sphinx.writers.text import TextTranslator
from sphinx.writers.manpage import ManualPageTranslator
from sphinx.util.osutil import relative_uri
from sphinx.locale import __
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()
self.body.append(
"<div id='%s' class='%s'></div>" % (
"<div id='%s' class='%s' width='%s' height='%s'>" % (
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(
"<script>document.addEventListener('ready', function() {" +
"SphinxGalleria.run('%s', %s, dataSource=%s).init()});</script>" % (
"</div><script type='module'>" +
"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,
json.dumps(node['options']),
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:
for image in node['images']:
self.body.append('[%s]' % image['description'])
self.body.append('[%s]' % image['alt'])
raise nodes.SkipNode
def texinfo_visit_galleria(self: TexinfoTranslator, node: galleria) -> None:
for image in node['images']:
self.body.append('[%s]' % image['description'])
self.body.append('[%s]' % image['alt'])
raise nodes.SkipNode
def text_visit_galleria(self: TextTranslator, node: galleria) -> None:
for image in node['images']:
self.body.append('[%s]' % image['description'])
self.body.append('[%s]' % image['alt'])
raise nodes.SkipNode
def gemini_visit_galleria(self, node: galleria) -> None:
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
def man_visit_galleria(self: ManualPageTranslator, node: galleria) -> None:
if 'description' in node.attributes:
self.body.append('[%s]' % node['description'])
if 'alt' in node.attributes:
self.body.append('[%s]' % node['alt'])
raise nodes.SkipNode
def align_choices(argument):
return directives.choice(argument, ('left', 'right', 'center'))
class GalleriaDirective(Directive):
has_content = False
required_arguments = 1
final_argument_whitespace = True
option_spec = {
"class": directives.unchanged,
"class": directives.class_option,
"galleria": directives.unchanged,
"description": directives.unchanged,
"alt": directives.unchanged,
"title": directives.unchanged,
"thumbsize": 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):
if not self.state.document.hasattr('galleria_nodes'):
self.state.document.galleria_nodes = {}
source = self.state.document.settings._source
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
if galleria_name and \
galleria_name in self.state.document.galleria_nodes:
node = self.state.document.galleria_nodes[galleria_name]
if galleria_name in document.galleria_nodes[source]:
node = document.galleria_nodes[source][galleria_name]
else:
node = galleria()
node['class'] = 'galleria'
node['options'] = {
'transition': 'fade'
'transition': 'fade',
'label_prev': __('Previous'),
'label_next': __('Next'),
'label_close': __('Close'),
'label_thumbnail': __('Thumbnail, click to enlarge'),
}
node['images'] = []
document.galleria_nodes[source][galleria_name] = node
created = True
@ -115,12 +150,18 @@ class GalleriaDirective(Directive):
if self.options.get('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
for path in images_path:
image = {}
image["description"] = self.options.get('description')
image["alt"] = self.options.get('alt')
image["title"] = self.options.get('title')
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
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;
}
}