file manager for chat

This commit is contained in:
Syed Amir
2017-08-02 16:24:28 +08:00
parent 1134f6fd0a
commit 573df6ef44
20 changed files with 5939 additions and 117 deletions
+333 -117
View File
@@ -51,6 +51,7 @@
<link rel="stylesheet" type="text/css" href="../assets/qweqwe/css/jquery.emojipicker.css">
<link rel="stylesheet" type="text/css" href="../assets/qweqwe/css/jquery.emojipicker.a.css">
<link href="../assets/layouts/layout/css/layout.min.css" rel="stylesheet" type="text/css" />
<link href="../assets/lightbox/dist/ekko-lightbox.css" rel="stylesheet">
<link href="../assets/layouts/layout/css/themes/darkblue.min.css" rel="stylesheet" type="text/css" id="style_color" />
<link href="../assets/layouts/layout/css/custom.min.css" rel="stylesheet" type="text/css" />
<!-- END THEME LAYOUT STYLES -->
@@ -79,6 +80,11 @@
margin-left: 200px;
}
}
.img-fluid {
max-width: 100% !important;
height: auto !important;
vertical-align: middle !important;
}
@media (min-width: 992px){
.page-sidebar {
width: 200px;
@@ -380,6 +386,8 @@
<div class="actions">
<a class="btn btn-circle btn-default" style="margin-left: 15px;" data-toggle="modal" href="#chat">
<i class="fa fa-plus"></i> Add Group </a>
<a class="btn btn-circle btn-default" style="margin-left: 15px;" data-toggle="modal" href="#doc">
<i class="fa fa-plus"></i> Upload </a>
<a href="javascript:window.open('trackorder2.html', 'Track Order', 'width=1000,height=600');" class="btn btn-circle btn-default tooltips" data-placement="bottom" data-original-title="Track Order">
<i class="fa fa-map-marker" aria-hidden="true"></i> Track Order
</a>
@@ -532,89 +540,7 @@
<!-- END CONTENT -->
</div>
<!-- END CONTENT BODY -->
</div>
<!-- END CONTENT -->
<!-- BEGIN QUICK SIDEBAR -->
<a href="javascript:;" class="page-quick-sidebar-toggler">
<i class="icon-login"></i>
</a>
<div class="page-quick-sidebar-wrapper" data-close-on-body-click="false">
<div class="page-quick-sidebar">
<ul class="nav nav-tabs">
<li class="active">
<a href="javascript:;" data-target="#quick_sidebar_tab_1" data-toggle="tab"> IMPORTER
</a>
</li>
<li>
<a href="javascript:;" data-target="#quick_sidebar_tab_2" data-toggle="tab"> FORWARDER
</a>
</li>
</ul>
<div class="tab-content">
<div class="tab-pane active page-quick-sidebar-chat" id="quick_sidebar_tab_1">
<div class="page-quick-sidebar-chat-users" data-rail-color="#ddd" data-wrapper-class="page-quick-sidebar-list">
<h3 class="list-heading">Members</h3>
<ul class="media-list list-items">
<li class="media">
<img class="media-object" src="../assets/layouts/layout/img/avatar2.jpg" alt="..." data-toggle="modal" href="#profile">
<div class="media-body">
<h4 class="media-heading">Lisa Wongs</h4>
<div class="media-heading-sub">Admin </div>
</div>
</li>
<li class="media">
<img class="media-object" src="../assets/layouts/layout/img/avatar1.jpg" alt="..." data-toggle="modal" href="#profile">
<div class="media-body">
<h4 class="media-heading">Bob Nilso</h4>
</div>
</li>
<li class="media">
<img class="media-object" src="../assets/layouts/layout/img/avatar3.jpg" alt="..." data-toggle="modal" href="#profile">
<div class="media-body">
<h4 class="media-heading">Richard Doe</h4>
</div>
</li>
</ul>
</div>
</div>
<div class="tab-pane page-quick-sidebar-chat" id="quick_sidebar_tab_2">
<div class="page-quick-sidebar-chat-users" data-rail-color="#ddd" data-wrapper-class="page-quick-sidebar-list">
<h3 class="list-heading">Members</h3>
<ul class="media-list list-items">
<li class="media">
<img class="media-object" src="../assets/layouts/layout/img/avatar1.jpg" alt="..." data-toggle="modal" href="#profile">
<div class="media-body">
<h4 class="media-heading">Bob Nilso</h4>
<div class="media-heading-sub">Admin </div>
</div>
</li>
<li class="media">
<img class="media-object" src="../assets/layouts/layout/img/avatar2.jpg" alt="..." data-toggle="modal" href="#profile">
<div class="media-body">
<h4 class="media-heading">Lisa Wongs</h4>
</div>
</li>
<li class="media">
<img class="media-object" src="../assets/layouts/layout/img/avatar3.jpg" alt="..." data-toggle="modal" href="#profile">
<div class="media-body">
<h4 class="media-heading">Richard Doe</h4>
</div>
</li>
<li align="center">
<div class="actions">
<a class="btn btn-circle btn-default" style="margin-left: 15px;" data-toggle="modal" href="#member">
<i class="fa fa-plus"></i> Add </a>
</div>
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
<!-- END QUICK SIDEBAR -->
</div>
<div class="modal fade" id="chat" tabindex="-1" role="chat" aria-hidden="true">
<div class="modal fade" id="chat" tabindex="-1" role="chat" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-body">
@@ -843,47 +769,240 @@
</div>
</div>
</div>
<div class="modal fade" id="img" tabindex="-1" role="img" aria-hidden="true">
<div class="portlet-body" >
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-body">
<div class="portlet light bordered">
<div class="portlet-title">
<div class="caption">
<span class="caption-subject bold font-purple-plum uppercase"> Documents </span>
</div>
</div>
<img src="../assets/global/img/cont.jpg" alt="Container" style="width:204px;height:128px;">
</div>
<button type="button" class="btn green"><i class="fa fa-upload" aria-hidden="true"></i> Upload </button>
<!-- Modal -->
<div class="modal fade" id="doc" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"></button>
<h4 class="modal-title" id="myModalLabel">File Manager</h4>
</div>
<div class="modal-body">
<div class="row">
<div class="col-md-12">
<div class="col-md-4">
<div class="btn-group ">
<a class="btn dropdown-toggle btn-default" data-toggle="dropdown" href="#">
<span class="glyphicon glyphicon-plus-sign"></span>File Type
<span class="caret"></span>
</a>
<ul class="dropdown-menu">
<li><a href="#">Documents</a></li>
<li><a href="#">Images</a></li>
<li><a href="#">Sounds</a></li>
<li><a href="#">Others</a></li>
</ul>
</div>
</div>
</div>
<br/>
<div class="col-md-4">
<div class="input-group">
<input type="text" class="form-control" placeholder="Search" name="q">
<div class="input-group-btn">
<button class="btn btn-default" type="submit"><i class="glyphicon glyphicon-search"></i></button>
</div>
</div>
</div>
<div class="col-md-4">
<div class="pull-right">
<button class="btn btn-default">
<span class="glyphicon glyphicon-refresh"></span>
</button>
<div class="btn-group">
<button id="list" type="button" class="btn btn-default"><span class="glyphicon glyphicon-align-justify"></span>
</button>
<button id="thumbnail" type="button" class="btn btn-default"> <span class="glyphicon glyphicon-th"></span>
</button>
</div>
<div class="btn-group ">
<a class="btn dropdown-toggle btn-default" data-toggle="dropdown" href="#">
Sort
<span class="caret"></span>
</a>
<ul class="dropdown-menu">
<li><a href="#">ID</a></li>
<li><a href="#">Title</a></li>
<li><a href="#">Date</a></li>
</ul>
</div>
</div>
</div>
</div>
</div>
<div class="modal fade" id="doc" tabindex="-1" role="doc" aria-hidden="true">
<div class="portlet-body" >
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-body">
<div class="portlet light bordered">
<div class="portlet-title">
<div class="caption">
<span class="caption-subject bold font-purple-plum uppercase"> Documents </span>
</div>
</div>
<img src="../assets/global/img/attachment.PNG" alt="Container" >
</div>
<button type="button" class="btn green"><i class="fa fa-upload" aria-hidden="true"></i> Upload </button>
</div>
</div>
<div class="col-md-12">
<div class="col-md-3">
<div class="row">
<div class="col-md-9">
<form action="#" class="dropzone dropzone-file-area" id="my-dropzone" style="width: 180px;margin-top: 0px;margin-left: 0px;margin-right: 0px;">
<h4 class="sbold">Drop files here or click to upload</h4>
</form>
</div>
</div>
</div>
<div id="thumbnails" class="col-md-9">
<div data-code="example-2">
<div class="row">
<div class="col-md-10" style="float: none; margin: 0 auto;">
<div class="row" style="margin-left:5px;margin-right:5px;margin-top:15px;margin-bottom:15px;">
<a href="https://unsplash.it/1200/768.jpg?image=251" data-toggle="lightbox" data-gallery="example-gallery" class="col-sm-4">
<img src="https://unsplash.it/600.jpg?image=251" class="img-fluid">
</a>
<a href="https://unsplash.it/1200/768.jpg?image=252" data-toggle="lightbox" data-gallery="example-gallery" class="col-sm-4">
<img src="https://unsplash.it/600.jpg?image=252" class="img-fluid">
</a>
<a href="https://unsplash.it/1200/768.jpg?image=253" data-toggle="lightbox" data-gallery="example-gallery" class="col-sm-4">
<img src="https://unsplash.it/600.jpg?image=253" class="img-fluid">
</a>
</div>
<div class="row" style="margin-left:5px;margin-right:5px;margin-top:10px;margin-bottom:10px;">
<a href="https://unsplash.it/1200/768.jpg?image=254" data-toggle="lightbox" data-gallery="example-gallery" class="col-sm-4">
<img src="https://unsplash.it/600.jpg?image=254" class="img-fluid">
</a>
<a href="https://unsplash.it/1200/768.jpg?image=255" data-toggle="lightbox" data-gallery="example-gallery" class="col-sm-4">
<img src="https://unsplash.it/600.jpg?image=255" class="img-fluid">
</a>
<a href="https://unsplash.it/1200/768.jpg?image=256" data-toggle="lightbox" data-gallery="example-gallery" class="col-sm-4">
<img src="https://unsplash.it/600.jpg?image=256" class="img-fluid">
</a>
</div>
</div>
</div>
</div>
</div>
<div class="col-md-9" id="lists" style="display:none;">
<table class="table table-hover" style="height:300px">
<thead>
<tr>
<th>ID</th>
<th>Date</th>
<th>Title</th>
<th class="text-center">Action</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>2017-08-02 13:45:22</td>
<td><a href="https://unsplash.it/1200/768.jpg?image=251" data-toggle="lightbox" data-gallery="example-gallery" class="col-sm-4">Container</a></td>
<td class="text-center"><a href="#" onclick="confirm('Are you confirm to delete this file?')" class="btn btn-xs"><span class="glyphicon glyphicon-trash"></span></a></td>
</tr>
<tr>
<td>2</td>
<td>2017-08-02 13:45:22</td>
<td><a href="https://unsplash.it/1200/768.jpg?image=251" data-toggle="lightbox" data-gallery="example-gallery" class="col-sm-4">Container</a></td>
<td class="text-center"><a href="#" onclick="confirm('Are you confirm to delete this file?')" class="btn btn-xs"><span class="glyphicon glyphicon-trash"></span></a></td>
</tr>
<tr>
<td>3</td>
<td>2017-08-02 13:45:22</td>
<td><a href="https://unsplash.it/1200/768.jpg?image=251" data-toggle="lightbox" data-gallery="example-gallery" class="col-sm-4">Container</a></td>
<td class="text-center"><a href="#" onclick="confirm('Are you confirm to delete this file?')" class="btn btn-xs"><span class="glyphicon glyphicon-trash"></span></a></td>
</tr>
<tr>
<td>4</td>
<td>2017-08-02 13:45:22</td>
<td><a href="https://unsplash.it/1200/768.jpg?image=251" data-toggle="lightbox" data-gallery="example-gallery" class="col-sm-4">Container</a></td>
<td class="text-center"><a href="#" onclick="confirm('Are you confirm to delete this file?')" class="btn btn-xs"><span class="glyphicon glyphicon-trash"></span></a></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- END CONTENT -->
<!-- BEGIN QUICK SIDEBAR -->
<a href="javascript:;" class="page-quick-sidebar-toggler">
<i class="icon-login"></i>
</a>
<div class="page-quick-sidebar-wrapper" data-close-on-body-click="false">
<div class="page-quick-sidebar">
<ul class="nav nav-tabs">
<li class="active">
<a href="javascript:;" data-target="#quick_sidebar_tab_1" data-toggle="tab"> IMPORTER
</a>
</li>
<li>
<a href="javascript:;" data-target="#quick_sidebar_tab_2" data-toggle="tab"> FORWARDER
</a>
</li>
</ul>
<div class="tab-content">
<div class="tab-pane active page-quick-sidebar-chat" id="quick_sidebar_tab_1">
<div class="page-quick-sidebar-chat-users" data-rail-color="#ddd" data-wrapper-class="page-quick-sidebar-list">
<h3 class="list-heading">Members</h3>
<ul class="media-list list-items">
<li class="media">
<img class="media-object" src="../assets/layouts/layout/img/avatar2.jpg" alt="..." data-toggle="modal" href="#profile">
<div class="media-body">
<h4 class="media-heading">Lisa Wongs</h4>
<div class="media-heading-sub">Admin </div>
</div>
</li>
<li class="media">
<img class="media-object" src="../assets/layouts/layout/img/avatar1.jpg" alt="..." data-toggle="modal" href="#profile">
<div class="media-body">
<h4 class="media-heading">Bob Nilso</h4>
</div>
</li>
<li class="media">
<img class="media-object" src="../assets/layouts/layout/img/avatar3.jpg" alt="..." data-toggle="modal" href="#profile">
<div class="media-body">
<h4 class="media-heading">Richard Doe</h4>
</div>
</li>
</ul>
</div>
</div>
<div class="tab-pane page-quick-sidebar-chat" id="quick_sidebar_tab_2">
<div class="page-quick-sidebar-chat-users" data-rail-color="#ddd" data-wrapper-class="page-quick-sidebar-list">
<h3 class="list-heading">Members</h3>
<ul class="media-list list-items">
<li class="media">
<img class="media-object" src="../assets/layouts/layout/img/avatar1.jpg" alt="..." data-toggle="modal" href="#profile">
<div class="media-body">
<h4 class="media-heading">Bob Nilso</h4>
<div class="media-heading-sub">Admin </div>
</div>
</li>
<li class="media">
<img class="media-object" src="../assets/layouts/layout/img/avatar2.jpg" alt="..." data-toggle="modal" href="#profile">
<div class="media-body">
<h4 class="media-heading">Lisa Wongs</h4>
</div>
</li>
<li class="media">
<img class="media-object" src="../assets/layouts/layout/img/avatar3.jpg" alt="..." data-toggle="modal" href="#profile">
<div class="media-body">
<h4 class="media-heading">Richard Doe</h4>
</div>
</li>
<li align="center">
<div class="actions">
<a class="btn btn-circle btn-default" style="margin-left: 15px;" data-toggle="modal" href="#member">
<i class="fa fa-plus"></i> Add </a>
</div>
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
<!-- END QUICK SIDEBAR -->
</div>
</div>
<!-- END CONTAINER -->
@@ -1017,5 +1136,102 @@
$('[data-toggle="popover"]').popover({trigger: 'focus'})
</script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/tether/1.2.0/js/tether.min.js" integrity="sha384-Plbmg8JY28KFelvJVai01l8WyZzrYWG825m+cZ0eDDS1f7d/js6ikvy1+X+guPIB" crossorigin="anonymous"></script>
<script src="../assets/lightbox/dist/ekko-lightbox.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/anchor-js/3.2.1/anchor.min.js"></script>
<script type="text/javascript">
$(document).ready(function ($) {
// delegate calls to data-toggle="lightbox"
$(document).on('click', '[data-toggle="lightbox"]:not([data-gallery="navigateTo"]):not([data-gallery="example-gallery-11"])', function(event) {
event.preventDefault();
return $(this).ekkoLightbox({
onShown: function() {
if (window.console) {
return console.log('Checking our the events huh?');
}
},
onNavigate: function(direction, itemIndex) {
if (window.console) {
return console.log('Navigating '+direction+'. Current item: '+itemIndex);
}
}
});
});
// disable wrapping
$(document).on('click', '[data-toggle="lightbox"][data-gallery="example-gallery-11"]', function(event) {
event.preventDefault();
return $(this).ekkoLightbox({
wrapping: false
});
});
//Programmatically call
$('#open-image').click(function (e) {
e.preventDefault();
$(this).ekkoLightbox();
});
$('#open-youtube').click(function (e) {
e.preventDefault();
$(this).ekkoLightbox();
});
// navigateTo
$(document).on('click', '[data-toggle="lightbox"][data-gallery="navigateTo"]', function(event) {
event.preventDefault();
return $(this).ekkoLightbox({
onShown: function() {
this.modal().on('click', '.modal-footer a', function(e) {
e.preventDefault();
this.navigateTo(2);
}.bind(this));
}
});
});
/**
* Documentation specific - ignore this
*/
anchors.options.placement = 'left';
anchors.add('h3');
$('code[data-code]').each(function() {
var $code = $(this),
$pair = $('div[data-code="'+$code.data('code')+'"]');
$code.hide();
var text = $code.text($pair.html()).html().trim().split("\n");
var indentLength = text[text.length - 1].match(/^\s+/)
indentLength = indentLength ? indentLength[0].length : 24;
var indent = '';
for(var i = 0; i < indentLength; i++)
indent += ' ';
if($code.data('trim') == 'all') {
for (var i = 0; i < text.length; i++)
text[i] = text[i].trim();
} else {
for (var i = 0; i < text.length; i++)
text[i] = text[i].replace(indent, ' ').replace(' ', '');
}
text = text.join("\n");
$code.html(text).show();
});
});
$('#thumbnail').on('click', function() {
document.getElementById("thumbnails").style.display = "";
document.getElementById("lists").style.display = "none";
});
$('#list').on('click', function() {
document.getElementById("thumbnails").style.display = "none";
document.getElementById("lists").style.display = "";
});
</script>
</body>
</html>
+6
View File
@@ -0,0 +1,6 @@
# Jetbrains
*.idea
# Node
node_modules
.DS_Store
+85
View File
@@ -0,0 +1,85 @@
module.exports = function (grunt) {
"use strict";
grunt.initConfig({
banner:
'/*!\n' +
' * Lightbox for Bootstrap by @ashleydw\n' +
' * https://github.com/ashleydw/lightbox\n' +
' *\n' +
' * License: https://github.com/ashleydw/lightbox/blob/master/LICENSE\n' +
' */',
less: {
dist: {
files: {
'dist/ekko-lightbox.css': 'ekko-lightbox.less'
}
}
},
babel: {
options: {
sourceMap: true,
modules: 'ignore'
},
dist: {
files: {
'dist/ekko-lightbox.js': 'ekko-lightbox.js',
}
}
},
uglify: {
options: {
sourceMap: true,
},
js: {
files: {
'dist/ekko-lightbox.min.js': 'dist/ekko-lightbox.js'
}
}
},
postcss: {
options: {
map: true,
processors: [
require('autoprefixer')({
browsers: ['last 2 versions']
}),
require('cssnano')()
]
},
dist: {
src: 'dist/*.css'
}
},
stamp: {
options: {
banner: '<%= banner %>\n+function ($) {\n',
footer: '\n}(jQuery);'
},
lightbox: {
files: {
src: ['dist/ekko-lightbox.js', 'dist/ekko-lightbox.min.js']
}
}
},
watch: {
babel: {
files: ['ekko-lightbox.js', 'ekko-lightbox.less'],
tasks: ['dev']
}
}
});
grunt.loadNpmTasks('grunt-stamp');
grunt.loadNpmTasks('grunt-babel');
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-cssmin');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-less');
grunt.loadNpmTasks('grunt-postcss');
grunt.registerTask('dev', ['babel', 'less']);
grunt.registerTask('dist', ['babel', 'less', 'stamp', 'postcss:dist', 'uglify']);
grunt.registerTask('default', ['dist']);
};
+9
View File
@@ -0,0 +1,9 @@
So, you're experiencing a problem?
If you're not sure how to use the lightbox, or are experiencing a problem with it, please ask on [StackOverflow](http://stackoverflow.com/) - you will most definitely get a faster response time and it leaves this GitHub issues for actual bugs and not support questions.
If you really do think you have a bug, please:
- [ ] Provide a link to your site or a full example
- [ ] Provide screenshots where appropriate
- [ ] Browser name and version
+21
View File
@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2011-2015 ashleydw
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.
+15
View File
@@ -0,0 +1,15 @@
Bootstrap Lightbox
========
A lightbox module for Bootstrap that supports images, YouTube videos, and galleries - built around Bootstrap's Modal plugin.
See the github page for docs: http://ashleydw.github.io/lightbox
Contributing
----
Instead of modifying the /dist/*.js JavaScript files directly, you should instead modify the ekko-lightbox.js file and run the grunt task.
Copyright and license
----
Code released under [the MIT license](https://github.com/ashleydw/lightbox/blob/master/LICENSE).
+29
View File
@@ -0,0 +1,29 @@
{
"name": "ekko-lightbox",
"version": "5.2.0",
"main": "./dist/ekko-lightbox.min.js",
"ignore": [
"**/.*",
"examples",
"node_modules",
"bower_components",
"test",
"tests"
],
"dependencies": {
"bootstrap": ">= 4.0.0-alpha.3"
},
"homepage": "https://github.com/ashleydw/lightbox",
"authors": [
"ashleydw <hello@ashleyd.ws>"
],
"description": "A lightbox gallery plugin for Bootstrap based on the modal plugin",
"keywords": [
"lightbox",
"gallery",
"bootstrap",
"jquery",
"modal"
],
"license": "MIT"
}
+2
View File
@@ -0,0 +1,2 @@
.ekko-lightbox-container{position:relative}.ekko-lightbox-container>div.ekko-lightbox-item{position:absolute;top:0;left:0;bottom:0;right:0;width:100%}.ekko-lightbox iframe{width:100%;height:100%}.ekko-lightbox-nav-overlay{z-index:1;position:absolute;top:0;left:0;width:100%;height:100%;display:-ms-flexbox;display:flex}.ekko-lightbox-nav-overlay a{-ms-flex:1;flex:1;display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;opacity:0;transition:opacity .5s;color:#fff;font-size:30px;z-index:1}.ekko-lightbox-nav-overlay a>*{-ms-flex-positive:1;flex-grow:1}.ekko-lightbox-nav-overlay a>:focus{outline:none}.ekko-lightbox-nav-overlay a span{padding:0 30px}.ekko-lightbox-nav-overlay a:last-child span{text-align:right}.ekko-lightbox-nav-overlay a:hover{text-decoration:none}.ekko-lightbox-nav-overlay a:focus{outline:none}.ekko-lightbox-nav-overlay a.disabled{cursor:default;visibility:hidden}.ekko-lightbox a:hover{opacity:1;text-decoration:none}.ekko-lightbox .modal-dialog{display:none}.ekko-lightbox .modal-footer{text-align:left}.ekko-lightbox-loader{position:absolute;top:0;left:0;bottom:0;right:0;width:100%;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;-ms-flex-pack:center;justify-content:center;-ms-flex-align:center;align-items:center}.ekko-lightbox-loader>div{width:40px;height:40px;position:relative;text-align:center}.ekko-lightbox-loader>div>div{width:100%;height:100%;border-radius:50%;background-color:#fff;opacity:.6;position:absolute;top:0;left:0;animation:a 2s infinite ease-in-out}.ekko-lightbox-loader>div>div:last-child{animation-delay:-1s}.modal-dialog .ekko-lightbox-loader>div>div{background-color:#333}@keyframes a{0%,to{transform:scale(0);-webkit-transform:scale(0)}50%{transform:scale(1);-webkit-transform:scale(1)}}
/*# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImVra28tbGlnaHRib3guY3NzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLHlCQUNFLGlCQUFtQixDQUNwQixBQUNELGdEQUNFLGtCQUFtQixBQUNuQixNQUFPLEFBQ1AsT0FBUSxBQUNSLFNBQVUsQUFDVixRQUFTLEFBQ1QsVUFBWSxDQUNiLEFBQ0Qsc0JBQ0UsV0FBWSxBQUNaLFdBQWEsQ0FDZCxBQUNELDJCQUNFLFVBQWEsQUFDYixrQkFBbUIsQUFDbkIsTUFBTyxBQUNQLE9BQVEsQUFDUixXQUFZLEFBQ1osWUFBYSxBQUNiLG9CQUFjLEFBQWQsWUFBYyxDQUNmLEFBQ0QsNkJBQ0UsV0FBUSxBQUFSLE9BQVEsQUFDUixvQkFBYyxBQUFkLGFBQWMsQUFDZCxzQkFBb0IsQUFBcEIsbUJBQW9CLEFBQ3BCLFVBQVcsQUFDWCx1QkFBeUIsQUFDekIsV0FBWSxBQUNaLGVBQWdCLEFBQ2hCLFNBQWEsQ0FDZCxBQUNELCtCQUNFLG9CQUFhLEFBQWIsV0FBYSxDQUNkLEFBQ0Qsb0NBQ0UsWUFBYyxDQUNmLEFBQ0Qsa0NBQ0UsY0FBZ0IsQ0FDakIsQUFDRCw2Q0FDRSxnQkFBa0IsQ0FDbkIsQUFDRCxtQ0FDRSxvQkFBc0IsQ0FDdkIsQUFDRCxtQ0FDRSxZQUFjLENBQ2YsQUFDRCxzQ0FDRSxlQUFnQixBQUNoQixpQkFBbUIsQ0FDcEIsQUFDRCx1QkFDRSxVQUFXLEFBQ1gsb0JBQXNCLENBQ3ZCLEFBQ0QsNkJBQ0UsWUFBYyxDQUNmLEFBQ0QsNkJBQ0UsZUFBaUIsQ0FDbEIsQUFDRCxzQkFDRSxrQkFBbUIsQUFDbkIsTUFBTyxBQUNQLE9BQVEsQUFDUixTQUFVLEFBQ1YsUUFBUyxBQUNULFdBQVksQUFDWixvQkFBYyxBQUFkLGFBQWMsQUFFZCwwQkFBdUIsQUFBdkIsc0JBQXVCLEFBRXZCLHFCQUF3QixBQUF4Qix1QkFBd0IsQUFFeEIsc0JBQW9CLEFBQXBCLGtCQUFvQixDQUNyQixBQUNELDBCQUNFLFdBQVksQUFDWixZQUFhLEFBQ2Isa0JBQW1CLEFBQ25CLGlCQUFtQixDQUNwQixBQUNELDhCQUNFLFdBQVksQUFDWixZQUFhLEFBQ2Isa0JBQW1CLEFBQ25CLHNCQUF1QixBQUN2QixXQUFhLEFBQ2Isa0JBQW1CLEFBQ25CLE1BQU8sQUFDUCxPQUFRLEFBQ1IsbUNBQTZDLENBQzlDLEFBQ0QseUNBQ0UsbUJBQXFCLENBQ3RCLEFBQ0QsNENBQ0UscUJBQXVCLENBQ3hCLEFBVUQsYUFDRSxNQUVFLG1CQUFvQixBQUNwQiwwQkFBNEIsQ0FDN0IsQUFDRCxJQUNFLG1CQUFvQixBQUNwQiwwQkFBNEIsQ0FDN0IsQ0FDRiIsImZpbGUiOiJla2tvLWxpZ2h0Ym94LmNzcyIsInNvdXJjZXNDb250ZW50IjpbIi5la2tvLWxpZ2h0Ym94LWNvbnRhaW5lciB7XG4gIHBvc2l0aW9uOiByZWxhdGl2ZTtcbn1cbi5la2tvLWxpZ2h0Ym94LWNvbnRhaW5lciA+IGRpdi5la2tvLWxpZ2h0Ym94LWl0ZW0ge1xuICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gIHRvcDogMDtcbiAgbGVmdDogMDtcbiAgYm90dG9tOiAwO1xuICByaWdodDogMDtcbiAgd2lkdGg6IDEwMCU7XG59XG4uZWtrby1saWdodGJveCBpZnJhbWUge1xuICB3aWR0aDogMTAwJTtcbiAgaGVpZ2h0OiAxMDAlO1xufVxuLmVra28tbGlnaHRib3gtbmF2LW92ZXJsYXkge1xuICB6LWluZGV4OiAxMDA7XG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgdG9wOiAwO1xuICBsZWZ0OiAwO1xuICB3aWR0aDogMTAwJTtcbiAgaGVpZ2h0OiAxMDAlO1xuICBkaXNwbGF5OiBmbGV4O1xufVxuLmVra28tbGlnaHRib3gtbmF2LW92ZXJsYXkgYSB7XG4gIGZsZXg6IDE7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gIG9wYWNpdHk6IDA7XG4gIHRyYW5zaXRpb246IG9wYWNpdHkgMC41cztcbiAgY29sb3I6ICNmZmY7XG4gIGZvbnQtc2l6ZTogMzBweDtcbiAgei1pbmRleDogMTAwO1xufVxuLmVra28tbGlnaHRib3gtbmF2LW92ZXJsYXkgYSA+ICoge1xuICBmbGV4LWdyb3c6IDE7XG59XG4uZWtrby1saWdodGJveC1uYXYtb3ZlcmxheSBhID4gKjpmb2N1cyB7XG4gIG91dGxpbmU6IG5vbmU7XG59XG4uZWtrby1saWdodGJveC1uYXYtb3ZlcmxheSBhIHNwYW4ge1xuICBwYWRkaW5nOiAwIDMwcHg7XG59XG4uZWtrby1saWdodGJveC1uYXYtb3ZlcmxheSBhOmxhc3QtY2hpbGQgc3BhbiB7XG4gIHRleHQtYWxpZ246IHJpZ2h0O1xufVxuLmVra28tbGlnaHRib3gtbmF2LW92ZXJsYXkgYTpob3ZlciB7XG4gIHRleHQtZGVjb3JhdGlvbjogbm9uZTtcbn1cbi5la2tvLWxpZ2h0Ym94LW5hdi1vdmVybGF5IGE6Zm9jdXMge1xuICBvdXRsaW5lOiBub25lO1xufVxuLmVra28tbGlnaHRib3gtbmF2LW92ZXJsYXkgYS5kaXNhYmxlZCB7XG4gIGN1cnNvcjogZGVmYXVsdDtcbiAgdmlzaWJpbGl0eTogaGlkZGVuO1xufVxuLmVra28tbGlnaHRib3ggYTpob3ZlciB7XG4gIG9wYWNpdHk6IDE7XG4gIHRleHQtZGVjb3JhdGlvbjogbm9uZTtcbn1cbi5la2tvLWxpZ2h0Ym94IC5tb2RhbC1kaWFsb2cge1xuICBkaXNwbGF5OiBub25lO1xufVxuLmVra28tbGlnaHRib3ggLm1vZGFsLWZvb3RlciB7XG4gIHRleHQtYWxpZ246IGxlZnQ7XG59XG4uZWtrby1saWdodGJveC1sb2FkZXIge1xuICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gIHRvcDogMDtcbiAgbGVmdDogMDtcbiAgYm90dG9tOiAwO1xuICByaWdodDogMDtcbiAgd2lkdGg6IDEwMCU7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIC8qIGVzdGFibGlzaCBmbGV4IGNvbnRhaW5lciAqL1xuICBmbGV4LWRpcmVjdGlvbjogY29sdW1uO1xuICAvKiBtYWtlIG1haW4gYXhpcyB2ZXJ0aWNhbCAqL1xuICBqdXN0aWZ5LWNvbnRlbnQ6IGNlbnRlcjtcbiAgLyogY2VudGVyIGl0ZW1zIHZlcnRpY2FsbHksIGluIHRoaXMgY2FzZSAqL1xuICBhbGlnbi1pdGVtczogY2VudGVyO1xufVxuLmVra28tbGlnaHRib3gtbG9hZGVyID4gZGl2IHtcbiAgd2lkdGg6IDQwcHg7XG4gIGhlaWdodDogNDBweDtcbiAgcG9zaXRpb246IHJlbGF0aXZlO1xuICB0ZXh0LWFsaWduOiBjZW50ZXI7XG59XG4uZWtrby1saWdodGJveC1sb2FkZXIgPiBkaXYgPiBkaXYge1xuICB3aWR0aDogMTAwJTtcbiAgaGVpZ2h0OiAxMDAlO1xuICBib3JkZXItcmFkaXVzOiA1MCU7XG4gIGJhY2tncm91bmQtY29sb3I6ICNmZmY7XG4gIG9wYWNpdHk6IDAuNjtcbiAgcG9zaXRpb246IGFic29sdXRlO1xuICB0b3A6IDA7XG4gIGxlZnQ6IDA7XG4gIGFuaW1hdGlvbjogc2stYm91bmNlIDJzIGluZmluaXRlIGVhc2UtaW4tb3V0O1xufVxuLmVra28tbGlnaHRib3gtbG9hZGVyID4gZGl2ID4gZGl2Omxhc3QtY2hpbGQge1xuICBhbmltYXRpb24tZGVsYXk6IC0xcztcbn1cbi5tb2RhbC1kaWFsb2cgLmVra28tbGlnaHRib3gtbG9hZGVyID4gZGl2ID4gZGl2IHtcbiAgYmFja2dyb3VuZC1jb2xvcjogIzMzMztcbn1cbkAtd2Via2l0LWtleWZyYW1lcyBzay1ib3VuY2Uge1xuICAwJSxcbiAgMTAwJSB7XG4gICAgLXdlYmtpdC10cmFuc2Zvcm06IHNjYWxlKDApO1xuICB9XG4gIDUwJSB7XG4gICAgLXdlYmtpdC10cmFuc2Zvcm06IHNjYWxlKDEpO1xuICB9XG59XG5Aa2V5ZnJhbWVzIHNrLWJvdW5jZSB7XG4gIDAlLFxuICAxMDAlIHtcbiAgICB0cmFuc2Zvcm06IHNjYWxlKDApO1xuICAgIC13ZWJraXQtdHJhbnNmb3JtOiBzY2FsZSgwKTtcbiAgfVxuICA1MCUge1xuICAgIHRyYW5zZm9ybTogc2NhbGUoMSk7XG4gICAgLXdlYmtpdC10cmFuc2Zvcm06IHNjYWxlKDEpO1xuICB9XG59XG4iXX0= */
+660
View File
@@ -0,0 +1,660 @@
/*!
* Lightbox for Bootstrap by @ashleydw
* https://github.com/ashleydw/lightbox
*
* License: https://github.com/ashleydw/lightbox/blob/master/LICENSE
*/
+function ($) {
'use strict';
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
var Lightbox = (function ($) {
var NAME = 'ekkoLightbox';
var JQUERY_NO_CONFLICT = $.fn[NAME];
var Default = {
title: '',
footer: '',
showArrows: true, //display the left / right arrows or not
wrapping: true, //if true, gallery loops infinitely
type: null, //force the lightbox into image / youtube mode. if null, or not image|youtube|vimeo; detect it
alwaysShowClose: false, //always show the close button, even if there is no title
loadingMessage: '<div class="ekko-lightbox-loader"><div><div></div><div></div></div></div>', // http://tobiasahlin.com/spinkit/
leftArrow: '<span>&#10094;</span>',
rightArrow: '<span>&#10095;</span>',
strings: {
close: 'Close',
fail: 'Failed to load image:',
type: 'Could not detect remote target type. Force the type using data-type'
},
doc: document, // if in an iframe can specify top.document
onShow: function onShow() {},
onShown: function onShown() {},
onHide: function onHide() {},
onHidden: function onHidden() {},
onNavigate: function onNavigate() {},
onContentLoaded: function onContentLoaded() {}
};
var Lightbox = (function () {
_createClass(Lightbox, null, [{
key: 'Default',
/**
Class properties:
_$element: null -> the <a> element currently being displayed
_$modal: The bootstrap modal generated
_$modalDialog: The .modal-dialog
_$modalContent: The .modal-content
_$modalBody: The .modal-body
_$modalHeader: The .modal-header
_$modalFooter: The .modal-footer
_$lightboxContainerOne: Container of the first lightbox element
_$lightboxContainerTwo: Container of the second lightbox element
_$lightboxBody: First element in the container
_$modalArrows: The overlayed arrows container
_$galleryItems: Other <a>'s available for this gallery
_galleryName: Name of the current data('gallery') showing
_galleryIndex: The current index of the _$galleryItems being shown
_config: {} the options for the modal
_modalId: unique id for the current lightbox
_padding / _border: CSS properties for the modal container; these are used to calculate the available space for the content
*/
get: function get() {
return Default;
}
}]);
function Lightbox($element, config) {
var _this = this;
_classCallCheck(this, Lightbox);
this._config = $.extend({}, Default, config);
this._$modalArrows = null;
this._galleryIndex = 0;
this._galleryName = null;
this._padding = null;
this._border = null;
this._titleIsShown = false;
this._footerIsShown = false;
this._wantedWidth = 0;
this._wantedHeight = 0;
this._touchstartX = 0;
this._touchendX = 0;
this._modalId = 'ekkoLightbox-' + Math.floor(Math.random() * 1000 + 1);
this._$element = $element instanceof jQuery ? $element : $($element);
this._isBootstrap3 = $.fn.modal.Constructor.VERSION[0] == 3;
var h4 = '<h4 class="modal-title">' + (this._config.title || "&nbsp;") + '</h4>';
var btn = '<button type="button" class="close" data-dismiss="modal" aria-label="' + this._config.strings.close + '"><span aria-hidden="true">&times;</span></button>';
var header = '<div class="modal-header' + (this._config.title || this._config.alwaysShowClose ? '' : ' hide') + '">' + (this._isBootstrap3 ? btn + h4 : h4 + btn) + '</div>';
var footer = '<div class="modal-footer' + (this._config.footer ? '' : ' hide') + '">' + (this._config.footer || "&nbsp;") + '</div>';
var body = '<div class="modal-body"><div class="ekko-lightbox-container"><div class="ekko-lightbox-item fade in show"></div><div class="ekko-lightbox-item fade"></div></div></div>';
var dialog = '<div class="modal-dialog" role="document"><div class="modal-content">' + header + body + footer + '</div></div>';
$(this._config.doc.body).append('<div id="' + this._modalId + '" class="ekko-lightbox modal fade" tabindex="-1" tabindex="-1" role="dialog" aria-hidden="true">' + dialog + '</div>');
this._$modal = $('#' + this._modalId, this._config.doc);
this._$modalDialog = this._$modal.find('.modal-dialog').first();
this._$modalContent = this._$modal.find('.modal-content').first();
this._$modalBody = this._$modal.find('.modal-body').first();
this._$modalHeader = this._$modal.find('.modal-header').first();
this._$modalFooter = this._$modal.find('.modal-footer').first();
this._$lightboxContainer = this._$modalBody.find('.ekko-lightbox-container').first();
this._$lightboxBodyOne = this._$lightboxContainer.find('> div:first-child').first();
this._$lightboxBodyTwo = this._$lightboxContainer.find('> div:last-child').first();
this._border = this._calculateBorders();
this._padding = this._calculatePadding();
this._galleryName = this._$element.data('gallery');
if (this._galleryName) {
this._$galleryItems = $(document.body).find('*[data-gallery="' + this._galleryName + '"]');
this._galleryIndex = this._$galleryItems.index(this._$element);
$(document).on('keydown.ekkoLightbox', this._navigationalBinder.bind(this));
// add the directional arrows to the modal
if (this._config.showArrows && this._$galleryItems.length > 1) {
this._$lightboxContainer.append('<div class="ekko-lightbox-nav-overlay"><a href="#">' + this._config.leftArrow + '</a><a href="#">' + this._config.rightArrow + '</a></div>');
this._$modalArrows = this._$lightboxContainer.find('div.ekko-lightbox-nav-overlay').first();
this._$lightboxContainer.on('click', 'a:first-child', function (event) {
event.preventDefault();
return _this.navigateLeft();
});
this._$lightboxContainer.on('click', 'a:last-child', function (event) {
event.preventDefault();
return _this.navigateRight();
});
this.updateNavigation();
}
}
this._$modal.on('show.bs.modal', this._config.onShow.bind(this)).on('shown.bs.modal', function () {
_this._toggleLoading(true);
_this._handle();
return _this._config.onShown.call(_this);
}).on('hide.bs.modal', this._config.onHide.bind(this)).on('hidden.bs.modal', function () {
if (_this._galleryName) {
$(document).off('keydown.ekkoLightbox');
$(window).off('resize.ekkoLightbox');
}
_this._$modal.remove();
return _this._config.onHidden.call(_this);
}).modal(this._config);
$(window).on('resize.ekkoLightbox', function () {
_this._resize(_this._wantedWidth, _this._wantedHeight);
});
this._$lightboxContainer.on('touchstart', function () {
_this._touchstartX = event.changedTouches[0].screenX;
}).on('touchend', function () {
_this._touchendX = event.changedTouches[0].screenX;
_this._swipeGesure();
});
}
_createClass(Lightbox, [{
key: 'element',
value: function element() {
return this._$element;
}
}, {
key: 'modal',
value: function modal() {
return this._$modal;
}
}, {
key: 'navigateTo',
value: function navigateTo(index) {
if (index < 0 || index > this._$galleryItems.length - 1) return this;
this._galleryIndex = index;
this.updateNavigation();
this._$element = $(this._$galleryItems.get(this._galleryIndex));
this._handle();
}
}, {
key: 'navigateLeft',
value: function navigateLeft() {
if (!this._$galleryItems) return;
if (this._$galleryItems.length === 1) return;
if (this._galleryIndex === 0) {
if (this._config.wrapping) this._galleryIndex = this._$galleryItems.length - 1;else return;
} else //circular
this._galleryIndex--;
this._config.onNavigate.call(this, 'left', this._galleryIndex);
return this.navigateTo(this._galleryIndex);
}
}, {
key: 'navigateRight',
value: function navigateRight() {
if (!this._$galleryItems) return;
if (this._$galleryItems.length === 1) return;
if (this._galleryIndex === this._$galleryItems.length - 1) {
if (this._config.wrapping) this._galleryIndex = 0;else return;
} else //circular
this._galleryIndex++;
this._config.onNavigate.call(this, 'right', this._galleryIndex);
return this.navigateTo(this._galleryIndex);
}
}, {
key: 'updateNavigation',
value: function updateNavigation() {
if (!this._config.wrapping) {
var $nav = this._$lightboxContainer.find('div.ekko-lightbox-nav-overlay');
if (this._galleryIndex === 0) $nav.find('a:first-child').addClass('disabled');else $nav.find('a:first-child').removeClass('disabled');
if (this._galleryIndex === this._$galleryItems.length - 1) $nav.find('a:last-child').addClass('disabled');else $nav.find('a:last-child').removeClass('disabled');
}
}
}, {
key: 'close',
value: function close() {
return this._$modal.modal('hide');
}
// helper private methods
}, {
key: '_navigationalBinder',
value: function _navigationalBinder(event) {
event = event || window.event;
if (event.keyCode === 39) return this.navigateRight();
if (event.keyCode === 37) return this.navigateLeft();
}
// type detection private methods
}, {
key: '_detectRemoteType',
value: function _detectRemoteType(src, type) {
type = type || false;
if (!type && this._isImage(src)) type = 'image';
if (!type && this._getYoutubeId(src)) type = 'youtube';
if (!type && this._getVimeoId(src)) type = 'vimeo';
if (!type && this._getInstagramId(src)) type = 'instagram';
if (!type || ['image', 'youtube', 'vimeo', 'instagram', 'video', 'url'].indexOf(type) < 0) type = 'url';
return type;
}
}, {
key: '_isImage',
value: function _isImage(string) {
return string && string.match(/(^data:image\/.*,)|(\.(jp(e|g|eg)|gif|png|bmp|webp|svg)((\?|#).*)?$)/i);
}
}, {
key: '_containerToUse',
value: function _containerToUse() {
var _this2 = this;
// if currently showing an image, fade it out and remove
var $toUse = this._$lightboxBodyTwo;
var $current = this._$lightboxBodyOne;
if (this._$lightboxBodyTwo.hasClass('in')) {
$toUse = this._$lightboxBodyOne;
$current = this._$lightboxBodyTwo;
}
$current.removeClass('in show');
setTimeout(function () {
if (!_this2._$lightboxBodyTwo.hasClass('in')) _this2._$lightboxBodyTwo.empty();
if (!_this2._$lightboxBodyOne.hasClass('in')) _this2._$lightboxBodyOne.empty();
}, 500);
$toUse.addClass('in show');
return $toUse;
}
}, {
key: '_handle',
value: function _handle() {
var $toUse = this._containerToUse();
this._updateTitleAndFooter();
var currentRemote = this._$element.attr('data-remote') || this._$element.attr('href');
var currentType = this._detectRemoteType(currentRemote, this._$element.attr('data-type') || false);
if (['image', 'youtube', 'vimeo', 'instagram', 'video', 'url'].indexOf(currentType) < 0) return this._error(this._config.strings.type);
switch (currentType) {
case 'image':
this._preloadImage(currentRemote, $toUse);
this._preloadImageByIndex(this._galleryIndex, 3);
break;
case 'youtube':
this._showYoutubeVideo(currentRemote, $toUse);
break;
case 'vimeo':
this._showVimeoVideo(this._getVimeoId(currentRemote), $toUse);
break;
case 'instagram':
this._showInstagramVideo(this._getInstagramId(currentRemote), $toUse);
break;
case 'video':
this._showHtml5Video(currentRemote, $toUse);
break;
default:
// url
this._loadRemoteContent(currentRemote, $toUse);
break;
}
return this;
}
}, {
key: '_getYoutubeId',
value: function _getYoutubeId(string) {
if (!string) return false;
var matches = string.match(/^.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|\&v=)([^#\&\?]*).*/);
return matches && matches[2].length === 11 ? matches[2] : false;
}
}, {
key: '_getVimeoId',
value: function _getVimeoId(string) {
return string && string.indexOf('vimeo') > 0 ? string : false;
}
}, {
key: '_getInstagramId',
value: function _getInstagramId(string) {
return string && string.indexOf('instagram') > 0 ? string : false;
}
// layout private methods
}, {
key: '_toggleLoading',
value: function _toggleLoading(show) {
show = show || false;
if (show) {
this._$modalDialog.css('display', 'none');
this._$modal.removeClass('in show');
$('.modal-backdrop').append(this._config.loadingMessage);
} else {
this._$modalDialog.css('display', 'block');
this._$modal.addClass('in show');
$('.modal-backdrop').find('.ekko-lightbox-loader').remove();
}
return this;
}
}, {
key: '_calculateBorders',
value: function _calculateBorders() {
return {
top: this._totalCssByAttribute('border-top-width'),
right: this._totalCssByAttribute('border-right-width'),
bottom: this._totalCssByAttribute('border-bottom-width'),
left: this._totalCssByAttribute('border-left-width')
};
}
}, {
key: '_calculatePadding',
value: function _calculatePadding() {
return {
top: this._totalCssByAttribute('padding-top'),
right: this._totalCssByAttribute('padding-right'),
bottom: this._totalCssByAttribute('padding-bottom'),
left: this._totalCssByAttribute('padding-left')
};
}
}, {
key: '_totalCssByAttribute',
value: function _totalCssByAttribute(attribute) {
return parseInt(this._$modalDialog.css(attribute), 10) + parseInt(this._$modalContent.css(attribute), 10) + parseInt(this._$modalBody.css(attribute), 10);
}
}, {
key: '_updateTitleAndFooter',
value: function _updateTitleAndFooter() {
var title = this._$element.data('title') || "";
var caption = this._$element.data('footer') || "";
this._titleIsShown = false;
if (title || this._config.alwaysShowClose) {
this._titleIsShown = true;
this._$modalHeader.css('display', '').find('.modal-title').html(title || "&nbsp;");
} else this._$modalHeader.css('display', 'none');
this._footerIsShown = false;
if (caption) {
this._footerIsShown = true;
this._$modalFooter.css('display', '').html(caption);
} else this._$modalFooter.css('display', 'none');
return this;
}
}, {
key: '_showYoutubeVideo',
value: function _showYoutubeVideo(remote, $containerForElement) {
var id = this._getYoutubeId(remote);
var query = remote.indexOf('&') > 0 ? remote.substr(remote.indexOf('&')) : '';
var width = this._$element.data('width') || 560;
var height = this._$element.data('height') || width / (560 / 315);
return this._showVideoIframe('//www.youtube.com/embed/' + id + '?badge=0&autoplay=1&html5=1' + query, width, height, $containerForElement);
}
}, {
key: '_showVimeoVideo',
value: function _showVimeoVideo(id, $containerForElement) {
var width = this._$element.data('width') || 500;
var height = this._$element.data('height') || width / (560 / 315);
return this._showVideoIframe(id + '?autoplay=1', width, height, $containerForElement);
}
}, {
key: '_showInstagramVideo',
value: function _showInstagramVideo(id, $containerForElement) {
// instagram load their content into iframe's so this can be put straight into the element
var width = this._$element.data('width') || 612;
var height = width + 80;
id = id.substr(-1) !== '/' ? id + '/' : id; // ensure id has trailing slash
$containerForElement.html('<iframe width="' + width + '" height="' + height + '" src="' + id + 'embed/" frameborder="0" allowfullscreen></iframe>');
this._resize(width, height);
this._config.onContentLoaded.call(this);
if (this._$modalArrows) //hide the arrows when showing video
this._$modalArrows.css('display', 'none');
this._toggleLoading(false);
return this;
}
}, {
key: '_showVideoIframe',
value: function _showVideoIframe(url, width, height, $containerForElement) {
// should be used for videos only. for remote content use loadRemoteContent (data-type=url)
height = height || width; // default to square
$containerForElement.html('<div class="embed-responsive embed-responsive-16by9"><iframe width="' + width + '" height="' + height + '" src="' + url + '" frameborder="0" allowfullscreen class="embed-responsive-item"></iframe></div>');
this._resize(width, height);
this._config.onContentLoaded.call(this);
if (this._$modalArrows) this._$modalArrows.css('display', 'none'); //hide the arrows when showing video
this._toggleLoading(false);
return this;
}
}, {
key: '_showHtml5Video',
value: function _showHtml5Video(url, $containerForElement) {
// should be used for videos only. for remote content use loadRemoteContent (data-type=url)
var width = this._$element.data('width') || 560;
var height = this._$element.data('height') || width / (560 / 315);
$containerForElement.html('<div class="embed-responsive embed-responsive-16by9"><video width="' + width + '" height="' + height + '" src="' + url + '" preload="auto" autoplay controls class="embed-responsive-item"></video></div>');
this._resize(width, height);
this._config.onContentLoaded.call(this);
if (this._$modalArrows) this._$modalArrows.css('display', 'none'); //hide the arrows when showing video
this._toggleLoading(false);
return this;
}
}, {
key: '_loadRemoteContent',
value: function _loadRemoteContent(url, $containerForElement) {
var _this3 = this;
var width = this._$element.data('width') || 560;
var height = this._$element.data('height') || 560;
var disableExternalCheck = this._$element.data('disableExternalCheck') || false;
this._toggleLoading(false);
// external urls are loading into an iframe
// local ajax can be loaded into the container itself
if (!disableExternalCheck && !this._isExternal(url)) {
$containerForElement.load(url, $.proxy(function () {
return _this3._$element.trigger('loaded.bs.modal');l;
}));
} else {
$containerForElement.html('<iframe src="' + url + '" frameborder="0" allowfullscreen></iframe>');
this._config.onContentLoaded.call(this);
}
if (this._$modalArrows) //hide the arrows when remote content
this._$modalArrows.css('display', 'none');
this._resize(width, height);
return this;
}
}, {
key: '_isExternal',
value: function _isExternal(url) {
var match = url.match(/^([^:\/?#]+:)?(?:\/\/([^\/?#]*))?([^?#]+)?(\?[^#]*)?(#.*)?/);
if (typeof match[1] === "string" && match[1].length > 0 && match[1].toLowerCase() !== location.protocol) return true;
if (typeof match[2] === "string" && match[2].length > 0 && match[2].replace(new RegExp(':(' + ({
"http:": 80,
"https:": 443
})[location.protocol] + ')?$'), "") !== location.host) return true;
return false;
}
}, {
key: '_error',
value: function _error(message) {
console.error(message);
this._containerToUse().html(message);
this._resize(300, 300);
return this;
}
}, {
key: '_preloadImageByIndex',
value: function _preloadImageByIndex(startIndex, numberOfTimes) {
if (!this._$galleryItems) return;
var next = $(this._$galleryItems.get(startIndex), false);
if (typeof next == 'undefined') return;
var src = next.attr('data-remote') || next.attr('href');
if (next.attr('data-type') === 'image' || this._isImage(src)) this._preloadImage(src, false);
if (numberOfTimes > 0) return this._preloadImageByIndex(startIndex + 1, numberOfTimes - 1);
}
}, {
key: '_preloadImage',
value: function _preloadImage(src, $containerForImage) {
var _this4 = this;
$containerForImage = $containerForImage || false;
var img = new Image();
if ($containerForImage) {
(function () {
// if loading takes > 200ms show a loader
var loadingTimeout = setTimeout(function () {
$containerForImage.append(_this4._config.loadingMessage);
}, 200);
img.onload = function () {
if (loadingTimeout) clearTimeout(loadingTimeout);
loadingTimeout = null;
var image = $('<img />');
image.attr('src', img.src);
image.addClass('img-fluid');
// backward compatibility for bootstrap v3
image.css('width', '100%');
$containerForImage.html(image);
if (_this4._$modalArrows) _this4._$modalArrows.css('display', ''); // remove display to default to css property
_this4._resize(img.width, img.height);
_this4._toggleLoading(false);
return _this4._config.onContentLoaded.call(_this4);
};
img.onerror = function () {
_this4._toggleLoading(false);
return _this4._error(_this4._config.strings.fail + (' ' + src));
};
})();
}
img.src = src;
return img;
}
}, {
key: '_swipeGesure',
value: function _swipeGesure() {
if (this._touchendX < this._touchstartX) {
return this.navigateRight();
}
if (this._touchendX > this._touchstartX) {
return this.navigateLeft();
}
}
}, {
key: '_resize',
value: function _resize(width, height) {
height = height || width;
this._wantedWidth = width;
this._wantedHeight = height;
// if width > the available space, scale down the expected width and height
var widthBorderAndPadding = this._padding.left + this._padding.right + this._border.left + this._border.right;
var maxWidth = Math.min(width + widthBorderAndPadding, this._config.doc.body.clientWidth);
if (width + widthBorderAndPadding > maxWidth) {
height = (maxWidth - widthBorderAndPadding) / width * height;
width = maxWidth;
} else width = width + widthBorderAndPadding;
var headerHeight = 0,
footerHeight = 0;
// as the resize is performed the modal is show, the calculate might fail
// if so, default to the default sizes
if (this._footerIsShown) footerHeight = this._$modalFooter.outerHeight(true) || 55;
if (this._titleIsShown) headerHeight = this._$modalHeader.outerHeight(true) || 67;
var borderPadding = this._padding.top + this._padding.bottom + this._border.bottom + this._border.top;
//calculated each time as resizing the window can cause them to change due to Bootstraps fluid margins
var margins = parseFloat(this._$modalDialog.css('margin-top')) + parseFloat(this._$modalDialog.css('margin-bottom'));
var maxHeight = Math.min(height, $(window).height() - borderPadding - margins - headerHeight - footerHeight);
if (height > maxHeight) {
// if height > the available height, scale down the width
var factor = Math.min(maxHeight / height, 1);
width = Math.ceil(factor * width);
}
this._$lightboxContainer.css('height', maxHeight);
this._$modalDialog.css('width', 'auto').css('maxWidth', width);
var modal = this._$modal.data('bs.modal');
if (modal) {
// v4 method is mistakenly protected
try {
modal._handleUpdate();
} catch (Exception) {
modal.handleUpdate();
}
}
return this;
}
}], [{
key: '_jQueryInterface',
value: function _jQueryInterface(config) {
var _this5 = this;
config = config || {};
return this.each(function () {
var $this = $(_this5);
var _config = $.extend({}, Lightbox.Default, $this.data(), typeof config === 'object' && config);
new Lightbox(_this5, _config);
});
}
}]);
return Lightbox;
})();
$.fn[NAME] = Lightbox._jQueryInterface;
$.fn[NAME].Constructor = Lightbox;
$.fn[NAME].noConflict = function () {
$.fn[NAME] = JQUERY_NO_CONFLICT;
return Lightbox._jQueryInterface;
};
return Lightbox;
})(jQuery);
//# sourceMappingURL=ekko-lightbox.js.map
}(jQuery);
File diff suppressed because one or more lines are too long
+2
View File
@@ -0,0 +1,2 @@
.ekko-lightbox-nav-overlay a:focus,.ekko-lightbox-nav-overlay a>:focus{outline:0}.ekko-lightbox-container{position:relative}.ekko-lightbox-container>div.ekko-lightbox-item{position:absolute;top:0;left:0;width:100%;transition:opacity .5s ease-in-out;opacity:1}.ekko-lightbox-nav-overlay{z-index:1;position:absolute;top:0;left:0;width:100%;height:100%;display:-ms-flexbox;display:flex}.ekko-lightbox-nav-overlay a{-ms-flex:1;flex:1;display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;opacity:0;transition:opacity .5s;color:#fff;font-size:30px;z-index:1}.ekko-lightbox-nav-overlay a>*{-ms-flex-positive:1;flex-grow:1}.ekko-lightbox-nav-overlay a span{padding:0 30px}.ekko-lightbox-nav-overlay a:last-child span{text-align:right}.ekko-lightbox-nav-overlay a:hover{text-decoration:none}.ekko-lightbox a:hover{opacity:1;text-decoration:none}.ekko-lightbox .modal-footer{text-align:left}.ekko-lightbox-loader{position:absolute;top:0;left:0;bottom:0;right:0;width:100%;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;-ms-flex-pack:center;justify-content:center;-ms-flex-align:center;align-items:center}.ekko-lightbox-loader>div{width:40px;height:40px;position:relative;text-align:center}.ekko-lightbox-loader>div>div{width:100%;height:100%;border-radius:50%;background-color:#fff;opacity:.6;position:absolute;top:0;left:0;animation:a 2s infinite ease-in-out}.ekko-lightbox-loader>div>div:last-child{animation-delay:-1s}@keyframes a{0%,to{transform:scale(0);-webkit-transform:scale(0)}50%{transform:scale(1);-webkit-transform:scale(1)}}
/*# sourceMappingURL=ekko-lightbox.min.css.map */
+1
View File
@@ -0,0 +1 @@
{"version":3,"sources":["dist/ekko-lightbox.css"],"names":[],"mappings":"AAkDA,uEACE,SAAS,CAnDX,yBACE,iBAAU,CAEZ,gDACE,kBACA,MACA,OACA,WACA,mCACA,SAAS,CAEX,2BACE,UACA,kBACA,MACA,OACA,WACA,YACA,oBACA,YAAS,CAEX,6BACE,WACI,OACJ,oBACA,aACA,sBACI,mBACJ,UACA,uBACA,WACA,eACA,SAAS,CAEX,+BACE,oBACI,WAAW,CAKjB,kCACE,cAAW,CAEb,6CACE,gBAAY,CAEd,mCACE,oBAAiB,CAKnB,uBACE,UACA,oBAAiB,CAEnB,6BACE,eAAY,CAEd,sBACE,kBACA,MACA,OACA,SACA,QACA,WACA,oBACA,aAEA,0BACI,sBAEJ,qBACI,uBAEJ,sBACI,kBAAa,CAEnB,0BACE,WACA,YACA,kBACA,iBAAY,CAEd,8BACE,WACA,YACA,kBACA,sBACA,WACA,kBACA,MACA,OACA,mCAAiC,CAEnC,yCACE,mBAAiB,CAEnB,aACE,MAEE,mBACA,0BAAmB,CAErB,IACE,mBACA,0BAAmB,CAAA,CAAA","file":"ekko-lightbox.min.css"}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+661
View File
@@ -0,0 +1,661 @@
const Lightbox = (($) => {
const NAME = 'ekkoLightbox'
const JQUERY_NO_CONFLICT = $.fn[NAME]
const Default = {
title: '',
footer: '',
showArrows: true, //display the left / right arrows or not
wrapping: true, //if true, gallery loops infinitely
type: null, //force the lightbox into image / youtube mode. if null, or not image|youtube|vimeo; detect it
alwaysShowClose: false, //always show the close button, even if there is no title
loadingMessage: '<div class="ekko-lightbox-loader"><div><div></div><div></div></div></div>', // http://tobiasahlin.com/spinkit/
leftArrow: '<span>&#10094;</span>',
rightArrow: '<span>&#10095;</span>',
strings: {
close: 'Close',
fail: 'Failed to load image:',
type: 'Could not detect remote target type. Force the type using data-type',
},
doc: document, // if in an iframe can specify top.document
onShow() {},
onShown() {},
onHide() {},
onHidden() {},
onNavigate() {},
onContentLoaded() {}
}
class Lightbox {
/**
Class properties:
_$element: null -> the <a> element currently being displayed
_$modal: The bootstrap modal generated
_$modalDialog: The .modal-dialog
_$modalContent: The .modal-content
_$modalBody: The .modal-body
_$modalHeader: The .modal-header
_$modalFooter: The .modal-footer
_$lightboxContainerOne: Container of the first lightbox element
_$lightboxContainerTwo: Container of the second lightbox element
_$lightboxBody: First element in the container
_$modalArrows: The overlayed arrows container
_$galleryItems: Other <a>'s available for this gallery
_galleryName: Name of the current data('gallery') showing
_galleryIndex: The current index of the _$galleryItems being shown
_config: {} the options for the modal
_modalId: unique id for the current lightbox
_padding / _border: CSS properties for the modal container; these are used to calculate the available space for the content
*/
static get Default() {
return Default
}
constructor($element, config) {
this._config = $.extend({}, Default, config)
this._$modalArrows = null
this._galleryIndex = 0
this._galleryName = null
this._padding = null
this._border = null
this._titleIsShown = false
this._footerIsShown = false
this._wantedWidth = 0
this._wantedHeight = 0
this._touchstartX = 0
this._touchendX = 0
this._modalId = `ekkoLightbox-${Math.floor((Math.random() * 1000) + 1)}`;
this._$element = $element instanceof jQuery ? $element : $($element)
this._isBootstrap3 = $.fn.modal.Constructor.VERSION[0] == 3;
let h4 = `<h4 class="modal-title">${this._config.title || "&nbsp;"}</h4>`;
let btn = `<button type="button" class="close" data-dismiss="modal" aria-label="${this._config.strings.close}"><span aria-hidden="true">&times;</span></button>`;
let header = `<div class="modal-header${this._config.title || this._config.alwaysShowClose ? '' : ' hide'}">`+(this._isBootstrap3 ? btn+h4 : h4+btn)+`</div>`;
let footer = `<div class="modal-footer${this._config.footer ? '' : ' hide'}">${this._config.footer || "&nbsp;"}</div>`;
let body = '<div class="modal-body"><div class="ekko-lightbox-container"><div class="ekko-lightbox-item fade in show"></div><div class="ekko-lightbox-item fade"></div></div></div>'
let dialog = `<div class="modal-dialog" role="document"><div class="modal-content">${header}${body}${footer}</div></div>`
$(this._config.doc.body).append(`<div id="${this._modalId}" class="ekko-lightbox modal fade" tabindex="-1" tabindex="-1" role="dialog" aria-hidden="true">${dialog}</div>`)
this._$modal = $(`#${this._modalId}`, this._config.doc)
this._$modalDialog = this._$modal.find('.modal-dialog').first()
this._$modalContent = this._$modal.find('.modal-content').first()
this._$modalBody = this._$modal.find('.modal-body').first()
this._$modalHeader = this._$modal.find('.modal-header').first()
this._$modalFooter = this._$modal.find('.modal-footer').first()
this._$lightboxContainer = this._$modalBody.find('.ekko-lightbox-container').first()
this._$lightboxBodyOne = this._$lightboxContainer.find('> div:first-child').first()
this._$lightboxBodyTwo = this._$lightboxContainer.find('> div:last-child').first()
this._border = this._calculateBorders()
this._padding = this._calculatePadding()
this._galleryName = this._$element.data('gallery')
if (this._galleryName) {
this._$galleryItems = $(document.body).find(`*[data-gallery="${this._galleryName}"]`)
this._galleryIndex = this._$galleryItems.index(this._$element)
$(document).on('keydown.ekkoLightbox', this._navigationalBinder.bind(this))
// add the directional arrows to the modal
if (this._config.showArrows && this._$galleryItems.length > 1) {
this._$lightboxContainer.append(`<div class="ekko-lightbox-nav-overlay"><a href="#">${this._config.leftArrow}</a><a href="#">${this._config.rightArrow}</a></div>`)
this._$modalArrows = this._$lightboxContainer.find('div.ekko-lightbox-nav-overlay').first()
this._$lightboxContainer.on('click', 'a:first-child', event => {
event.preventDefault()
return this.navigateLeft()
})
this._$lightboxContainer.on('click', 'a:last-child', event => {
event.preventDefault()
return this.navigateRight()
})
this.updateNavigation()
}
}
this._$modal
.on('show.bs.modal', this._config.onShow.bind(this))
.on('shown.bs.modal', () => {
this._toggleLoading(true)
this._handle()
return this._config.onShown.call(this)
})
.on('hide.bs.modal', this._config.onHide.bind(this))
.on('hidden.bs.modal', () => {
if (this._galleryName) {
$(document).off('keydown.ekkoLightbox')
$(window).off('resize.ekkoLightbox')
}
this._$modal.remove()
return this._config.onHidden.call(this)
})
.modal(this._config)
$(window).on('resize.ekkoLightbox', () => {
this._resize(this._wantedWidth, this._wantedHeight)
})
this._$lightboxContainer
.on('touchstart', () => {
this._touchstartX = event.changedTouches[0].screenX;
})
.on('touchend', () => {
this._touchendX = event.changedTouches[0].screenX;
this._swipeGesure();
})
}
element() {
return this._$element;
}
modal() {
return this._$modal;
}
navigateTo(index) {
if (index < 0 || index > this._$galleryItems.length-1)
return this
this._galleryIndex = index
this.updateNavigation()
this._$element = $(this._$galleryItems.get(this._galleryIndex))
this._handle();
}
navigateLeft() {
if(!this._$galleryItems)
return;
if (this._$galleryItems.length === 1)
return
if (this._galleryIndex === 0) {
if (this._config.wrapping)
this._galleryIndex = this._$galleryItems.length - 1
else
return
}
else //circular
this._galleryIndex--
this._config.onNavigate.call(this, 'left', this._galleryIndex)
return this.navigateTo(this._galleryIndex)
}
navigateRight() {
if(!this._$galleryItems)
return;
if (this._$galleryItems.length === 1)
return
if (this._galleryIndex === this._$galleryItems.length - 1) {
if (this._config.wrapping)
this._galleryIndex = 0
else
return
}
else //circular
this._galleryIndex++
this._config.onNavigate.call(this, 'right', this._galleryIndex)
return this.navigateTo(this._galleryIndex)
}
updateNavigation() {
if (!this._config.wrapping) {
let $nav = this._$lightboxContainer.find('div.ekko-lightbox-nav-overlay')
if (this._galleryIndex === 0)
$nav.find('a:first-child').addClass('disabled')
else
$nav.find('a:first-child').removeClass('disabled')
if (this._galleryIndex === this._$galleryItems.length - 1)
$nav.find('a:last-child').addClass('disabled')
else
$nav.find('a:last-child').removeClass('disabled')
}
}
close() {
return this._$modal.modal('hide');
}
// helper private methods
_navigationalBinder(event) {
event = event || window.event;
if (event.keyCode === 39)
return this.navigateRight()
if (event.keyCode === 37)
return this.navigateLeft()
}
// type detection private methods
_detectRemoteType(src, type) {
type = type || false;
if(!type && this._isImage(src))
type = 'image';
if(!type && this._getYoutubeId(src))
type = 'youtube';
if(!type && this._getVimeoId(src))
type = 'vimeo';
if(!type && this._getInstagramId(src))
type = 'instagram';
if(!type || ['image', 'youtube', 'vimeo', 'instagram', 'video', 'url'].indexOf(type) < 0)
type = 'url';
return type;
}
_isImage(string) {
return string && string.match(/(^data:image\/.*,)|(\.(jp(e|g|eg)|gif|png|bmp|webp|svg)((\?|#).*)?$)/i)
}
_containerToUse() {
// if currently showing an image, fade it out and remove
let $toUse = this._$lightboxBodyTwo
let $current = this._$lightboxBodyOne
if(this._$lightboxBodyTwo.hasClass('in')) {
$toUse = this._$lightboxBodyOne
$current = this._$lightboxBodyTwo
}
$current.removeClass('in show')
setTimeout(() => {
if(!this._$lightboxBodyTwo.hasClass('in'))
this._$lightboxBodyTwo.empty()
if(!this._$lightboxBodyOne.hasClass('in'))
this._$lightboxBodyOne.empty()
}, 500)
$toUse.addClass('in show')
return $toUse
}
_handle() {
let $toUse = this._containerToUse()
this._updateTitleAndFooter()
let currentRemote = this._$element.attr('data-remote') || this._$element.attr('href')
let currentType = this._detectRemoteType(currentRemote, this._$element.attr('data-type') || false)
if(['image', 'youtube', 'vimeo', 'instagram', 'video', 'url'].indexOf(currentType) < 0)
return this._error(this._config.strings.type)
switch(currentType) {
case 'image':
this._preloadImage(currentRemote, $toUse)
this._preloadImageByIndex(this._galleryIndex, 3)
break;
case 'youtube':
this._showYoutubeVideo(currentRemote, $toUse);
break;
case 'vimeo':
this._showVimeoVideo(this._getVimeoId(currentRemote), $toUse);
break;
case 'instagram':
this._showInstagramVideo(this._getInstagramId(currentRemote), $toUse);
break;
case 'video':
this._showHtml5Video(currentRemote, $toUse);
break;
default: // url
this._loadRemoteContent(currentRemote, $toUse);
break;
}
return this;
}
_getYoutubeId(string) {
if(!string)
return false;
let matches = string.match(/^.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|\&v=)([^#\&\?]*).*/)
return (matches && matches[2].length === 11) ? matches[2] : false
}
_getVimeoId(string) {
return string && string.indexOf('vimeo') > 0 ? string : false
}
_getInstagramId(string) {
return string && string.indexOf('instagram') > 0 ? string : false
}
// layout private methods
_toggleLoading(show) {
show = show || false
if(show) {
this._$modalDialog.css('display', 'none')
this._$modal.removeClass('in show')
$('.modal-backdrop').append(this._config.loadingMessage)
}
else {
this._$modalDialog.css('display', 'block')
this._$modal.addClass('in show')
$('.modal-backdrop').find('.ekko-lightbox-loader').remove()
}
return this;
}
_calculateBorders() {
return {
top: this._totalCssByAttribute('border-top-width'),
right: this._totalCssByAttribute('border-right-width'),
bottom: this._totalCssByAttribute('border-bottom-width'),
left: this._totalCssByAttribute('border-left-width'),
}
}
_calculatePadding() {
return {
top: this._totalCssByAttribute('padding-top'),
right: this._totalCssByAttribute('padding-right'),
bottom: this._totalCssByAttribute('padding-bottom'),
left: this._totalCssByAttribute('padding-left'),
}
}
_totalCssByAttribute(attribute) {
return parseInt(this._$modalDialog.css(attribute), 10) +
parseInt(this._$modalContent.css(attribute), 10) +
parseInt(this._$modalBody.css(attribute), 10)
}
_updateTitleAndFooter() {
let title = this._$element.data('title') || ""
let caption = this._$element.data('footer') || ""
this._titleIsShown = false
if (title || this._config.alwaysShowClose) {
this._titleIsShown = true
this._$modalHeader.css('display', '').find('.modal-title').html(title || "&nbsp;")
}
else
this._$modalHeader.css('display', 'none')
this._footerIsShown = false
if (caption) {
this._footerIsShown = true
this._$modalFooter.css('display', '').html(caption)
}
else
this._$modalFooter.css('display', 'none')
return this;
}
_showYoutubeVideo(remote, $containerForElement) {
let id = this._getYoutubeId(remote)
let query = remote.indexOf('&') > 0 ? remote.substr(remote.indexOf('&')) : ''
let width = this._$element.data('width') || 560
let height = this._$element.data('height') || width / ( 560/315 )
return this._showVideoIframe(
`//www.youtube.com/embed/${id}?badge=0&autoplay=1&html5=1${query}`,
width,
height,
$containerForElement
);
}
_showVimeoVideo(id, $containerForElement) {
let width = this._$element.data('width') || 500
let height = this._$element.data('height') || width / ( 560/315 )
return this._showVideoIframe(id + '?autoplay=1', width, height, $containerForElement)
}
_showInstagramVideo(id, $containerForElement) {
// instagram load their content into iframe's so this can be put straight into the element
let width = this._$element.data('width') || 612
let height = width + 80;
id = id.substr(-1) !== '/' ? id + '/' : id; // ensure id has trailing slash
$containerForElement.html(`<iframe width="${width}" height="${height}" src="${id}embed/" frameborder="0" allowfullscreen></iframe>`);
this._resize(width, height);
this._config.onContentLoaded.call(this);
if (this._$modalArrows) //hide the arrows when showing video
this._$modalArrows.css('display', 'none');
this._toggleLoading(false);
return this;
}
_showVideoIframe(url, width, height, $containerForElement) { // should be used for videos only. for remote content use loadRemoteContent (data-type=url)
height = height || width; // default to square
$containerForElement.html(`<div class="embed-responsive embed-responsive-16by9"><iframe width="${width}" height="${height}" src="${url}" frameborder="0" allowfullscreen class="embed-responsive-item"></iframe></div>`);
this._resize(width, height);
this._config.onContentLoaded.call(this);
if (this._$modalArrows)
this._$modalArrows.css('display', 'none'); //hide the arrows when showing video
this._toggleLoading(false);
return this;
}
_showHtml5Video(url, $containerForElement) { // should be used for videos only. for remote content use loadRemoteContent (data-type=url)
let width = this._$element.data('width') || 560
let height = this._$element.data('height') || width / ( 560/315 )
$containerForElement.html(`<div class="embed-responsive embed-responsive-16by9"><video width="${width}" height="${height}" src="${url}" preload="auto" autoplay controls class="embed-responsive-item"></video></div>`);
this._resize(width, height);
this._config.onContentLoaded.call(this);
if (this._$modalArrows)
this._$modalArrows.css('display', 'none'); //hide the arrows when showing video
this._toggleLoading(false);
return this;
}
_loadRemoteContent(url, $containerForElement) {
let width = this._$element.data('width') || 560;
let height = this._$element.data('height') || 560;
let disableExternalCheck = this._$element.data('disableExternalCheck') || false;
this._toggleLoading(false);
// external urls are loading into an iframe
// local ajax can be loaded into the container itself
if (!disableExternalCheck && !this._isExternal(url)) {
$containerForElement.load(url, $.proxy(() => {
return this._$element.trigger('loaded.bs.modal');l
}));
} else {
$containerForElement.html(`<iframe src="${url}" frameborder="0" allowfullscreen></iframe>`);
this._config.onContentLoaded.call(this);
}
if (this._$modalArrows) //hide the arrows when remote content
this._$modalArrows.css('display', 'none')
this._resize(width, height);
return this;
}
_isExternal(url) {
let match = url.match(/^([^:\/?#]+:)?(?:\/\/([^\/?#]*))?([^?#]+)?(\?[^#]*)?(#.*)?/);
if (typeof match[1] === "string" && match[1].length > 0 && match[1].toLowerCase() !== location.protocol)
return true;
if (typeof match[2] === "string" && match[2].length > 0 && match[2].replace(new RegExp(`:(${{
"http:": 80,
"https:": 443
}[location.protocol]})?$`), "") !== location.host)
return true;
return false;
}
_error( message ) {
console.error(message);
this._containerToUse().html(message);
this._resize(300, 300);
return this;
}
_preloadImageByIndex(startIndex, numberOfTimes) {
if(!this._$galleryItems)
return;
let next = $(this._$galleryItems.get(startIndex), false)
if(typeof next == 'undefined')
return
let src = next.attr('data-remote') || next.attr('href')
if (next.attr('data-type') === 'image' || this._isImage(src))
this._preloadImage(src, false)
if(numberOfTimes > 0)
return this._preloadImageByIndex(startIndex + 1, numberOfTimes-1);
}
_preloadImage( src, $containerForImage) {
$containerForImage = $containerForImage || false
let img = new Image();
if ($containerForImage) {
// if loading takes > 200ms show a loader
let loadingTimeout = setTimeout(() => {
$containerForImage.append(this._config.loadingMessage)
}, 200)
img.onload = () => {
if(loadingTimeout)
clearTimeout(loadingTimeout)
loadingTimeout = null;
let image = $('<img />');
image.attr('src', img.src);
image.addClass('img-fluid');
// backward compatibility for bootstrap v3
image.css('width', '100%');
$containerForImage.html(image);
if (this._$modalArrows)
this._$modalArrows.css('display', '') // remove display to default to css property
this._resize(img.width, img.height);
this._toggleLoading(false);
return this._config.onContentLoaded.call(this);
};
img.onerror = () => {
this._toggleLoading(false);
return this._error(this._config.strings.fail+` ${src}`);
};
}
img.src = src;
return img;
}
_swipeGesure() {
if (this._touchendX < this._touchstartX) {
return this.navigateRight();
}
if (this._touchendX > this._touchstartX) {
return this.navigateLeft();
}
}
_resize( width, height ) {
height = height || width
this._wantedWidth = width
this._wantedHeight = height
// if width > the available space, scale down the expected width and height
let widthBorderAndPadding = this._padding.left + this._padding.right + this._border.left + this._border.right
let maxWidth = Math.min(width + widthBorderAndPadding, this._config.doc.body.clientWidth)
if((width + widthBorderAndPadding) > maxWidth) {
height = ((maxWidth - widthBorderAndPadding) / width) * height
width = maxWidth
} else
width = (width + widthBorderAndPadding)
let headerHeight = 0,
footerHeight = 0
// as the resize is performed the modal is show, the calculate might fail
// if so, default to the default sizes
if (this._footerIsShown)
footerHeight = this._$modalFooter.outerHeight(true) || 55
if (this._titleIsShown)
headerHeight = this._$modalHeader.outerHeight(true) || 67
let borderPadding = this._padding.top + this._padding.bottom + this._border.bottom + this._border.top
//calculated each time as resizing the window can cause them to change due to Bootstraps fluid margins
let margins = parseFloat(this._$modalDialog.css('margin-top')) + parseFloat(this._$modalDialog.css('margin-bottom'));
let maxHeight = Math.min(height, $(window).height() - borderPadding - margins - headerHeight - footerHeight);
if(height > maxHeight) {
// if height > the available height, scale down the width
let factor = Math.min(maxHeight / height, 1);
width = Math.ceil(factor * width);
}
this._$lightboxContainer.css('height', maxHeight)
this._$modalDialog.css('width', 'auto') .css('maxWidth', width);
let modal = this._$modal.data('bs.modal');
if (modal) {
// v4 method is mistakenly protected
try {
modal._handleUpdate();
} catch(Exception) {
modal.handleUpdate();
}
}
return this;
}
static _jQueryInterface(config) {
config = config || {}
return this.each(() => {
let $this = $(this)
let _config = $.extend(
{},
Lightbox.Default,
$this.data(),
typeof config === 'object' && config
)
new Lightbox(this, _config)
})
}
}
$.fn[NAME] = Lightbox._jQueryInterface
$.fn[NAME].Constructor = Lightbox
$.fn[NAME].noConflict = () => {
$.fn[NAME] = JQUERY_NO_CONFLICT
return Lightbox._jQueryInterface
}
return Lightbox
})(jQuery)
export default Lightbox
+134
View File
@@ -0,0 +1,134 @@
.ekko-lightbox {
&-container {
position:relative;
> div.ekko-lightbox-item {
position:absolute;
top:0;
left:0;
bottom:0;
right:0;
width:100%;
}
}
iframe {
width: 100%;
height: 100%;
}
&-nav-overlay {
z-index:100;
position: absolute;
top:0;
left:0;
width:100%;
height:100%;
display: flex;
a {
flex: 1;
display:flex;
align-items: center;
opacity: 0;
transition: opacity 0.5s;
color: #fff;
font-size:30px;
z-index:100;
> * {
flex-grow:1;
&:focus {
outline: none;
}
}
span {
padding:0 30px;
}
&:last-child span {
text-align: right;
}
&:hover {
text-decoration: none;
}
&:focus {
outline: none;
}
&.disabled {
cursor: default;
visibility: hidden;
}
}
}
a:hover {
opacity: 1;
text-decoration: none;
}
.modal-dialog {
display:none;
}
.modal-footer {
text-align: left;
}
// http://tobiasahlin.com/spinkit/
&-loader {
position:absolute;
top:0;
left:0;
bottom:0;
right:0;
width:100%;
display: flex; /* establish flex container */
flex-direction: column; /* make main axis vertical */
justify-content: center; /* center items vertically, in this case */
align-items: center;
> div {
width: 40px;
height: 40px;
position: relative;
text-align: center;
> div {
width: 100%;
height: 100%;
border-radius: 50%;
background-color: #fff;
opacity: 0.6;
position: absolute;
top: 0;
left: 0;
animation: sk-bounce 2.0s infinite ease-in-out;
&:last-child {
animation-delay: -1.0s;
}
}
}
}
.modal-dialog &-loader {
> div > div {
background-color:#333;
}
}
@-webkit-keyframes sk-bounce {
0%, 100% { -webkit-transform: scale(0.0) }
50% { -webkit-transform: scale(1.0) }
}
@keyframes sk-bounce {
0%, 100% {
transform: scale(0.0);
-webkit-transform: scale(0.0);
} 50% {
transform: scale(1.0);
-webkit-transform: scale(1.0);
}
}
}
+596
View File
@@ -0,0 +1,596 @@
<!DOCTYPE html>
<html>
<head>
<title>Bootstrap Lightbox</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<link href="../dist/ekko-lightbox.css" rel="stylesheet">
<!-- for documentation only -->
<style type="text/css">
div.row > div > div.row {
margin-bottom: 15px;
}
html {
background-color: #02709e;
}
body {
background: #fefefe;
padding-bottom: 50px;
}
div.top-container {
padding-top:100px;
background-color: #02709e;
color:#ccc;
}
div.top-container h1 {
color:white;
}
div.top-container a {
color:#ccc;
border-bottom:1px dotted white;
}
div.top-container a:hover {
color: white;
cursor:pointer;
border-bottom:1px solid white;
text-decoration: none;
}
div.top-header {
margin-bottom:100px;
}
h2 {
background-color:#02709e;
color:white;
display:inline-block;
padding:6px;
margin-top:100px;
}
h3 {
padding-bottom:5px;
margin-bottom:10px;
border-bottom:1px solid #f2f2f2;
margin-top: 50px;
}
h4 {
margin-top:25px;
}
figure {
position: relative;
}
figure figcaption {
font-size: 22px;
color: #fff;
text-decoration: none;
bottom: 10px;
right: 20px;
position: absolute;
background-color: #000;
}
code[data-code], code.block-code {
display:block;
overflow:scroll;
font-size:12px;
white-space: pre;
}
table {
font-size:12px;
}
.footer {
text-align: center;
}
.footer span {
margin-top:100px;
font-size:12px;
background-color:#02709e;
color:white;
display:inline-block;
padding:6px;
}
.footer span a {
color:#ccc;
border-bottom:1px dotted white;
}
.footer span a:hover {
cursor:pointer;
color: white;
border-bottom:1px solid white;
text-decoration: none;
}
a.anchorjs-link {
color:black;
}
a.anchorjs-link:hover {
color:#02709e;
text-decoration: none;
}
</style>
</head>
<body>
<div class="bs3-notice">
<p><strong>NB!:</strong> This page is intended to demonstrate that the lightbox works with Bootstrap 3 - the CSS classes for the layout use BS4 so this page won't display correctly.</p>
<p>Use this page only to check the lightbox works with BS3.</p>
</div>
<div class="top-container">
<div class="container">
<div class="row">
<div class="col-md-10 offset-md-1">
<div class="top-header">
<h1>Lightbox for Bootstrap</h1>
<p class="lead">Utilizes Bootstraps modal plugin to implement a lightbox gallery - <a href="//github.com/ashleydw/lightbox">GitHub</a></p>
<div class="text-center">
<iframe src="http://ghbtns.com/github-btn.html?user=ashleydw&repo=lightbox&type=watch&count=true" allowtransparency="true" frameborder="0" scrolling="0" width="100 " height="20"></iframe>
<iframe src="http://ghbtns.com/github-btn.html?user=ashleydw&repo=lightbox&type=fork&count=true" allowtransparency="true" frameborder="0" scrolling="0" width="100" height="20"></iframe>
<iframe src="http://ghbtns.com/github-btn.html?user=ashleydw&repo=lightbox&type=follow&count=true" allowtransparency="true" frameborder="0" scrolling="0" width="160" height="20"></iframe>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="container">
<div class="row">
<div class="col-md-10 offset-md-1">
<h2>Install</h2>
<p>Grab the latest CSS / JS files from the CDN: <a href="https://cdnjs.com/libraries/ekko-lightbox">https://cdnjs.com/libraries/ekko-lightbox</a>.</p>
<p>Or, with bower: <code>bower install ekko-lightbox --save</code></p>
<p>Or, download the files directly: <a href="https://github.com/ashleydw/lightbox/tree/master/dist">https://github.com/ashleydw/lightbox/tree/master/dist</a></p>
<br /><br />
<p>Place this near on your page, probably near the end of the body section:</p>
<code class="block-code">$(document).on('click', '[data-toggle="lightbox"]', function(event) {
event.preventDefault();
$(this).ekkoLightbox();
});</code>
<br /><br />
<p>Then simply add <code>data-toggle</code> to your anchor tags.</p>
<code class="block-code">&lt;a href=&quot;https://unsplash.it/1200/768.jpg?image=251&quot; data-toggle=&quot;lightbox&quot;&gt;
&lt;img src=&quot;https://unsplash.it/600.jpg?image=251&quot; class=&quot;img-fluid&quot;&gt;
&lt;/a&gt;
</code>
<br /><br />
<p>Obviously, you need Bootstrap. Made for Bootstrap v4 but *should* work with v3.</p>
<h2>Options</h2>
<p>Options are passed down to the modal object so you can also use any of the <a href="http://getbootstrap.com/javascript/#modals-usage">original modal options</a>.</p>
<p>Pass the options to the calling function as an object, or set defaults using <code>$.fn.ekkoLightbox.defaults</code> (excluding modal default options, notable: title, footer, remote)</p>
<div class="table-responsive">
<table class="table table-bordered">
<thead>
<tr>
<th>Name</th>
<th>type</th>
<th>default</th>
<th>description</th>
<th>data-*</th>
</tr>
</thead>
<tbody>
<tr>
<td>leftArrow / rightArrow</td>
<td>html</td>
<td><code>&#10094;</code> / <code>&#10095;</code></td>
<td>HTML for the arrows</td>
<td></td>
</tr>
<tr>
<td>width / height</td>
<td>integer</td>
<td></td>
<td>Force the width / height</td>
<td><code>data-(width|height)="[0-9]+"</code></td>
</tr>
<tr>
<td>alwaysShowClose</td>
<td>boolean</td>
<td><code>false</code></td>
<td>Always show the close button, even if no title is present</td>
<td></td>
</tr>
<tr>
<td>loadingMessage</td>
<td>html</td>
<td>A fancy loader</td>
<td>HTML injected for loading</td>
<td></td>
</tr>
<tr>
<td>showArrows</td>
<td>bool</td>
<td>true</td>
<td>Disable the navigation overlay</td>
<td></td>
</tr>
</tbody>
</table>
</div>
<code class="block-code">$(this).ekkoLightbox({
alwaysShowClose: true,
onShown: function() {
console.log('Checking our the events huh?');
},
onNavigate: function(direction, itemIndex)
console.log('Navigating '+direction+'. Current item: '+itemIndex);
}
...
});</code>
<br /><br />
<p>The following options are specified per element.</p>
<div class="table-responsive">
<table class="table table-bordered">
<thead>
<tr>
<th>Name</th>
<th>Description</th>
<th>Example</th>
</tr>
</thead>
<tbody>
<tr>
<td>remote</td>
<td>If you can't/don't want to set the href property of an element</td>
<td><code>data-remote="http://www...."</code></td>
</tr>
<tr>
<td>gallery</td>
<td>For grouping elements</td>
<td><code>data-gallery="gallery-name"</code></td>
</tr>
<tr>
<td>type</td>
<td>Force the lightbox into image/YouTube mode.</td>
<td><code>data-type="(image|youtube|vimeo)"</code></td>
</tr>
</tbody>
</table>
</div>
<code class="block-code">&lt;a href=&quot;https://unsplash.it/1200/768.jpg?image=251&quot; data-toggle=&quot;lightbox&quot; data-gallery=&quot;example-gallery&quot; data-type=&quot;image&quot;&gt;
&lt;img src=&quot;https://unsplash.it/600.jpg?image=251&quot; class=&quot;img-fluid&quot;&gt;
&lt;/a&gt;</code>
<h2>Events</h2>
<p>Events can be hooked into, set the the same as options above.</p>
<div class="table-responsive">
<table class="table table-bordered">
<thead>
<tr>
<th>Name</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>onContentLoaded</td>
<td>Fired when content (image/video/remote page etc) has been fully loaded.</td>
</tr>
<tr>
<td>onNavigate</td>
<td>Fired before navigating a gallery.</td>
</tr>
<tr>
<td>onShow/onShown/onHide/onHidden</td>
<td>Inherited from the bootstrap modal.</td>
</tr>
</tbody>
</table>
</div>
<h2>Examples</h2>
<p>Thanks to <a href="https://unsplash.it/">https://unsplash.it/</a> for the images.</p>
<ul>
<li><a href="#single-image">Single Image</a></li>
<li><a href="#image-gallery">Image Gallery</a></li>
<li><a href="#videos">Videos</a></li>
<li><a href="#videos-gallery">Gallery of Videos</a></li>
<li><a href="#mixed-gallery">Mixed gallery</a></li>
<li><a href="#programatically-call">Programmatically call</a></li>
<li><a href="#data-remote">Via <code>data-remote</code></a></li>
<li><a href="#force-type">Force type</a></li>
<li><a href="#hidden-elements">Hidden elements</a></li>
<li><a href="#remote-content">Remote content</a></li>
</ul>
<h3 id="single-image">Single Image</h3>
<p>Note: uses modal plugin title option via <code>data-title</code>, and the custom footer tag using <code>data-footer</code></p>
<div class="row">
<div class="offset-sm-4 col-sm-3" data-code="example-1">
<a href="https://unsplash.it/1200/768.jpg?image=250" data-toggle="lightbox" data-title="A random title" data-footer="A custom footer text">
<img src="https://unsplash.it/600.jpg?image=250" class="img-fluid">
</a>
</div>
</div>
<code class="html" data-code="example-1"></code>
<h3 id="image-gallery">Image Gallery</h3>
<p>Galleries are created by adding the <code>data-gallery</code> attribute.</p>
<div data-code="example-2">
<div class="row">
<div class="offset-md-2 col-md-8">
<div class="row">
<a href="https://unsplash.it/1200/768.jpg?image=251" data-toggle="lightbox" data-gallery="example-gallery" class="col-sm-4">
<img src="https://unsplash.it/600.jpg?image=251" class="img-fluid">
</a>
<a href="https://unsplash.it/1200/768.jpg?image=252" data-toggle="lightbox" data-gallery="example-gallery" class="col-sm-4">
<img src="https://unsplash.it/600.jpg?image=252" class="img-fluid">
</a>
<a href="https://unsplash.it/1200/768.jpg?image=253" data-toggle="lightbox" data-gallery="example-gallery" class="col-sm-4">
<img src="https://unsplash.it/600.jpg?image=253" class="img-fluid">
</a>
</div>
<div class="row">
<a href="https://unsplash.it/1200/768.jpg?image=254" data-toggle="lightbox" data-gallery="example-gallery" class="col-sm-4">
<img src="https://unsplash.it/600.jpg?image=254" class="img-fluid">
</a>
<a href="https://unsplash.it/1200/768.jpg?image=255" data-toggle="lightbox" data-gallery="example-gallery" class="col-sm-4">
<img src="https://unsplash.it/600.jpg?image=255" class="img-fluid">
</a>
<a href="https://unsplash.it/1200/768.jpg?image=256" data-toggle="lightbox" data-gallery="example-gallery" class="col-sm-4">
<img src="https://unsplash.it/600.jpg?image=256" class="img-fluid">
</a>
</div>
</div>
</div>
</div>
<code class="html" data-code="example-2"></code>
<h3 id="videos">Videos</h3>
<h4>YouTube</h4>
<p>You can use various YouTube URL formats, the regex used is: <code>/^.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|\&v=)([^#\&\?]*).*/</code></p>
<div data-code="example-3">
<p><a href="https://www.youtube.com/watch?v=dQw4w9WgXcQ" data-toggle="lightbox">Justin Bieber - Love Yourself</a></p>
<p><a href="http://youtu.be/b0jqPvpn3sY" data-toggle="lightbox">Tame Impala - Elephant (using youtu.be link)</a></p>
<p><a href="https://www.youtube.com/watch?v=oyEuk8j8imI&rel=0" data-toggle="lightbox">Justin Bieber - Love Yourself</a> (suppress related videos with <code>&rel=0</code>)</p>
</div>
<code data-code="example-3" data-trim="all"></code>
<h4>Vimeo</h4>
<p>You cannot embed Vimeo videos using the standard url (ie http://vimeo.com/80629469); you must link to the embed source (ie player.vimeo.com/video/80629469). This will mean your link url - if the JavaScript fails, will open the full screen player (try opening the first link below in a new tab); the solution to this is to set the lightbox source directly - the second link below does this.</p>
<div data-code="example-3-b">
<p><a href="http://player.vimeo.com/video/80629469" data-toggle="lightbox">City Lights - from Colin Rich (using embed link)</a></p>
<p><a href="http://vimeo.com/80629469" data-remote="http://player.vimeo.com/video/80629469" data-toggle="lightbox">City Lights - from Colin Rich</a> (with reccommended <code>data-remote</code> setting)</p>
</div>
<code data-code="example-3-b" data-trim="all"></code>
<h4>Instagram</h4>
<p></p>
<div data-code="example-3-c">
<p><a href="http://instagram.com/p/pZfG1fPfuX/" data-toggle="lightbox" data-title="Plug for our new service">GOtags.co.uk</a></p>
<p>This also works with photos: <a href="//instagram.com/p/0wbypvPfmQ/" data-toggle="lightbox">GOtags.co.uk</a></p>
</div>
<code data-code="example-3-c" data-trim="all"></code>
<h4>Forcing width</h4>
<p>Set the width of the video</p>
<div data-code="example-3-d">
<p><a href="https://www.youtube.com/watch?v=e-ORhEE9VVg" data-toggle="lightbox">Taylor Swift - Blank Space (standard)</a></p>
<p><a href="https://www.youtube.com/watch?v=e-ORhEE9VVg" data-toggle="lightbox" data-width="640">Taylor Swift - Blank Space (640 x 360)</a></p>
<p><a href="https://www.youtube.com/watch?v=e-ORhEE9VVg" data-toggle="lightbox" data-width="1280">Taylor Swift - Blank Space (1280 x 780)</a></p>
</div>
<code data-code="example-3-d" data-trim="all"></code>
<!-- i hope your coworkers think you're listening to some justin and taylor -->
<h3 id="videos-gallery">Gallery of Videos</h3>
<div class="row">
<div class="offset-md-1 col-md-10">
<div class="row" data-code="example-4">
<a href="http://www.youtube.com/watch?v=k6mFF3VmVAs" data-toggle="lightbox" data-gallery="youtubevideos" class="col-sm-4">
<img src="//i1.ytimg.com/vi/yP11r5n5RNg/mqdefault.jpg" class="img-fluid">
</a>
<a href="http://youtu.be/iQ4D273C7Ac" data-toggle="lightbox" data-gallery="youtubevideos" class="col-sm-4">
<img src="//i1.ytimg.com/vi/iQ4D273C7Ac/mqdefault.jpg" class="img-fluid">
</a>
<a href="//www.youtube.com/embed/b0jqPvpn3sY" data-toggle="lightbox" data-gallery="youtubevideos" class="col-sm-4">
<img src="//i1.ytimg.com/vi/b0jqPvpn3sY/mqdefault.jpg" class="img-fluid">
</a>
</div>
</div>
</div>
<code data-code="example-4"></code>
<h3 id="mixed-gallery">Mixed gallery</h3>
<div class="row">
<div class="offset-md-1 col-md-10">
<div class="row flex-items-xs-center" data-code="example-5">
<a href="http://www.youtube.com/watch?v=k6mFF3VmVAs" data-toggle="lightbox" data-gallery="mixedgallery" class="col-sm-4">
<img src="//i1.ytimg.com/vi/yP11r5n5RNg/mqdefault.jpg" class="img-fluid">
</a>
<a href="https://unsplash.it/1200/768.jpg?image=257" data-toggle="lightbox" data-gallery="mixedgallery" class="col-sm-4">
<img src="https://unsplash.it/600.jpg?image=257" class="img-fluid">
</a>
<a href="http://vimeo.com/80629469" data-remote="http://player.vimeo.com/video/80629469" data-toggle="lightbox" data-gallery="mixedgallery" class="col-sm-4">
<img src="//b.vimeocdn.com/ts/458/070/458070637_200.jpg" class="img-fluid">
</a>
</div>
</div>
</div>
<code data-code="example-5"></code>
<h3 id="programatically-call">Programmatically call</h3>
<p>These two examples are opened via the JavaScript at the bottom of the source.</p>
<div class="row">
<div class="offset-md-1 col-md-10">
<div class="row" data-code="example-6">
<a href="https://unsplash.it/1200/768.jpg?image=258" id="open-image" class="col-sm-4">
<img src="https://unsplash.it/600.jpg?image=258" class="img-fluid">
</a>
<a href="http://youtu.be/iQ4D273C7Ac" id="open-youtube" class="col-sm-4">
<img src="//i1.ytimg.com/vi/iQ4D273C7Ac/mqdefault.jpg" class="img-fluid">
</a>
</div>
</div>
</div>
<code data-code="example-6"></code>
<code class="block-code">$(&#39;#open-image&#39;).click(function (e) {
e.preventDefault();
$(this).ekkoLightbox();
});
$(&#39;#open-youtube&#39;).click(function (e) {
e.preventDefault();
$(this).ekkoLightbox();
});</code>
<h3 id="data-remote">Via <code>data-remote</code></h3>
<p>Neither of these are <code>&lt;a /&gt;</code> tags, so both rely on the <code>data-remote</code> attribute.</p>
<div class="row">
<div class="offset-md-1 col-md-10">
<div class="row" data-code="example-7">
<img src="https://unsplash.it/600.jpg?image=259" data-toggle="lightbox" data-remote="https://unsplash.it/1200/768.jpg?image=259" class="img-fluid col-sm-4">
<img src="//i1.ytimg.com/vi/b0jqPvpn3sY/mqdefault.jpg" data-toggle="lightbox" data-remote="//www.youtube.com/embed/b0jqPvpn3sY" class="img-fluid col-sm-4">
</div>
</div>
</div>
<code data-code="example-7"></code>
<h3 id="force-type">Force type</h3>
<p>If the images you are linking to have no extension, the lightbox cannot detect that is an image; therefore you need to tell the lightbox what <code>data-type</code> it is.</p>
<p>Current allowed types are: <code>['image', 'youtube', 'vimeo', 'instagram', 'video', 'url']</code></p>
<div data-code="example-8">
<p><a href="https://unsplash.it/1200/768?image=260" data-title="Force image display" data-footer="The remote of this modal has no extension (https://unsplash.it/1200/768?image=260) but works because the type is forced." data-toggle="lightbox" data-type="image">Click here for an image, but with no extension.</a></p>
<p><a href="https://unsplash.it/1200/768?image=261" data-footer="Without the type forced, the lightbox will remote load the content" data-toggle="lightbox">This link is missing the type attribute, and will iframe the image.</a></p>
<p><a href="http://www.youtube.com/watch?v=b0jqPvpn3sY" data-toggle="lightbox" data-type="image">This link is linking to a YouTube video, but forcing an image.</a></p>
</div>
<code data-code="example-8"></code>
<h3 id="hidden-elements">Hidden elements</h3>
<p>Facebook style, only show a few images but have a large gallery</p>
<div class="row">
<div class="offset-md-2 col-md-8">
<div class="row" data-code="example-9">
<a href="https://unsplash.it/1200/768.jpg?image=263" data-toggle="lightbox" data-gallery="hidden-images" class="col-sm-4">
<img src="https://unsplash.it/600.jpg?image=263" class="img-fluid">
</a>
<a href="https://unsplash.it/1200/768.jpg?image=264" data-toggle="lightbox" data-gallery="hidden-images" class="col-sm-4">
<img src="https://unsplash.it/600.jpg?image=264" class="img-fluid">
</a>
<a href="https://unsplash.it/1200/768.jpg?image=265" data-toggle="lightbox" data-gallery="hidden-images" class="col-sm-4">
<img src="https://unsplash.it/600.jpg?image=265" class="img-fluid">
</a>
<!-- elements not showing, use data-remote -->
<div data-toggle="lightbox" data-gallery="hidden-images" data-remote="https://unsplash.it/1200/768.jpg?image=264" data-title="Hidden item 1"></div>
<div data-toggle="lightbox" data-gallery="hidden-images" data-remote="//www.youtube.com/embed/b0jqPvpn3sY" data-title="Hidden item 2"></div>
<div data-toggle="lightbox" data-gallery="hidden-images" data-remote="https://unsplash.it/1200/768.jpg?image=265" data-title="Hidden item 3"></div>
<div data-toggle="lightbox" data-gallery="hidden-images" data-remote="https://unsplash.it/1200/768.jpg?image=266" data-title="Hidden item 4"></div>
<div data-toggle="lightbox" data-gallery="hidden-images" data-remote="https://unsplash.it/1200/768.jpg?image=267" data-title="Hidden item 5"></div>
</div>
</div>
</div>
<code data-code="example-9"></code>
<h3 id="remote-content">Remote content</h3>
<p>Given a URL, that is not an image or video (including unforced types), load the content using an iFrame.</p>
<div class="row">
<div class="offset-md-1 col-md-10" data-code="example-10">
<div class="row">
<p class="col-sm-3"><a href="http://getbootstrap.com" data-title="Bootstrap" data-width="1200" data-toggle="lightbox" data-gallery="remoteload">Bootstrap Docs</a></p>
</div>
</div>
</div>
<code data-code="example-10"></code>
<p class="footer"><span>Built by me, <a href="https://ashleyd.ws">ashleydw</a></span></p>
</div>
</div>
</div>
<script src="//ajax.googleapis.com/ajax/libs/jquery/3.0.0/jquery.min.js" integrity="sha384-THPy051/pYDQGanwU6poAc/hOdQxjnOEXzbT+OuUAFqNqFjL+4IGLBgCJC3ZOShY" crossorigin="anonymous"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/tether/1.2.0/js/tether.min.js" integrity="sha384-Plbmg8JY28KFelvJVai01l8WyZzrYWG825m+cZ0eDDS1f7d/js6ikvy1+X+guPIB" crossorigin="anonymous"></script>
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="../dist/ekko-lightbox.js"></script>
<!-- for documentation only -->
<script src="//cdnjs.cloudflare.com/ajax/libs/anchor-js/3.2.1/anchor.min.js"></script>
<script type="text/javascript">
$(document).ready(function ($) {
// delegate calls to data-toggle="lightbox"
$(document).on('click', '[data-toggle="lightbox"]:not([data-gallery="navigateTo"])', function(event) {
event.preventDefault();
return $(this).ekkoLightbox({
onShown: function() {
if (window.console) {
return console.log('Checking our the events huh?');
}
},
onNavigate: function(direction, itemIndex) {
if (window.console) {
return console.log('Navigating '+direction+'. Current item: '+itemIndex);
}
}
});
});
//Programmatically call
$('#open-image').click(function (e) {
e.preventDefault();
$(this).ekkoLightbox();
});
$('#open-youtube').click(function (e) {
e.preventDefault();
$(this).ekkoLightbox();
});
// navigateTo
$(document).on('click', '[data-toggle="lightbox"][data-gallery="navigateTo"]', function(event) {
event.preventDefault();
return $(this).ekkoLightbox({
onShown: function() {
this.modal().on('click', '.modal-footer a', function(e) {
e.preventDefault();
this.navigateTo(2);
}.bind(this));
}
});
});
/**
* Documentation specific - ignore this
*/
anchors.options.placement = 'left';
anchors.add('h3');
$('code[data-code]').each(function() {
var $code = $(this),
$pair = $('div[data-code="'+$code.data('code')+'"]');
$code.hide();
var text = $code.text($pair.html()).html().trim().split("\n");
var indentLength = text[text.length - 1].match(/^\s+/)
indentLength = indentLength ? indentLength[0].length : 24;
var indent = '';
for(var i = 0; i < indentLength; i++)
indent += ' ';
if($code.data('trim') == 'all') {
for (var i = 0; i < text.length; i++)
text[i] = text[i].trim();
} else {
for (var i = 0; i < text.length; i++)
text[i] = text[i].replace(indent, ' ').replace(' ', '');
}
text = text.join("\n");
$code.html(text).show();
});
});
</script>
</body>
</html>
+675
View File
@@ -0,0 +1,675 @@
<!DOCTYPE html>
<html>
<head>
<title>Bootstrap Lightbox</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css">
<link href="../dist/ekko-lightbox.css" rel="stylesheet">
<!-- for documentation only -->
<style type="text/css">
div.row > div > div.row {
margin-bottom: 15px;
}
html {
background-color: #02709e;
}
body {
background: #fefefe;
padding-bottom: 50px;
}
div.top-container {
padding-top:100px;
background-color: #02709e;
color:#ccc;
}
div.top-container h1 {
color:white;
}
div.top-container a {
color:#ccc;
border-bottom:1px dotted white;
}
div.top-container a:hover {
color: white;
cursor:pointer;
border-bottom:1px solid white;
text-decoration: none;
}
div.top-header {
margin-bottom:100px;
}
h2 {
background-color:#02709e;
color:white;
display:inline-block;
padding:6px;
margin-top:100px;
}
h3 {
padding-bottom:5px;
margin-bottom:10px;
border-bottom:1px solid #f2f2f2;
margin-top: 50px;
}
h4:not(.modal-title) {
margin-top:25px;
}
figure {
position: relative;
}
figure figcaption {
font-size: 22px;
color: #fff;
text-decoration: none;
bottom: 10px;
right: 20px;
position: absolute;
background-color: #000;
}
code[data-code], code.block-code {
display:block;
overflow:scroll;
font-size:12px;
white-space: pre;
}
table {
font-size:12px;
}
.footer {
text-align: center;
}
.footer span {
margin-top:100px;
font-size:12px;
background-color:#02709e;
color:white;
display:inline-block;
padding:6px;
}
.footer span a {
color:#ccc;
border-bottom:1px dotted white;
}
.footer span a:hover {
cursor:pointer;
color: white;
border-bottom:1px solid white;
text-decoration: none;
}
a.anchorjs-link {
color:black;
}
a.anchorjs-link:hover {
color:#02709e;
text-decoration: none;
}
</style>
</head>
<body>
<div class="top-container">
<div class="container">
<div class="row">
<div class="col-md-10 offset-md-1">
<div class="top-header">
<h1>Lightbox for Bootstrap</h1>
<p class="lead">Utilizes Bootstraps modal plugin to implement a lightbox gallery - <a href="//github.com/ashleydw/lightbox">GitHub</a></p>
<div class="text-center">
<iframe src="http://ghbtns.com/github-btn.html?user=ashleydw&repo=lightbox&type=watch&count=true" allowtransparency="true" frameborder="0" scrolling="0" width="100 " height="20"></iframe>
<iframe src="http://ghbtns.com/github-btn.html?user=ashleydw&repo=lightbox&type=fork&count=true" allowtransparency="true" frameborder="0" scrolling="0" width="100" height="20"></iframe>
<iframe src="http://ghbtns.com/github-btn.html?user=ashleydw&repo=lightbox&type=follow&count=true" allowtransparency="true" frameborder="0" scrolling="0" width="160" height="20"></iframe>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="container">
<div class="row">
<div class="col-md-10 offset-md-1">
<h2>Install</h2>
<p>Grab the latest CSS / JS files from the CDN: <a href="https://cdnjs.com/libraries/ekko-lightbox">https://cdnjs.com/libraries/ekko-lightbox</a>.</p>
<p>Or, with bower: <code>bower install ekko-lightbox --save</code></p>
<p>Or, download the files directly: <a href="https://github.com/ashleydw/lightbox/tree/master/dist">https://github.com/ashleydw/lightbox/tree/master/dist</a></p>
<br /><br />
<p>Place this near on your page, probably near the end of the body section:</p>
<code class="block-code">$(document).on('click', '[data-toggle="lightbox"]', function(event) {
event.preventDefault();
$(this).ekkoLightbox();
});</code>
<br /><br />
<p>Then simply add <code>data-toggle</code> to your anchor tags.</p>
<code class="block-code">&lt;a href=&quot;https://unsplash.it/1200/768.jpg?image=251&quot; data-toggle=&quot;lightbox&quot;&gt;
&lt;img src=&quot;https://unsplash.it/600.jpg?image=251&quot; class=&quot;img-fluid&quot;&gt;
&lt;/a&gt;
</code>
<br /><br />
<p>Obviously, you need Bootstrap. Made for Bootstrap v4 but *should* work with v3.</p>
<h2>Options</h2>
<p>Options are passed down to the modal object so you can also use any of the <a href="http://getbootstrap.com/javascript/#modals-usage">original modal options</a>.</p>
<p>Pass the options to the calling function as an object, or set defaults using <code>$.fn.ekkoLightbox.defaults</code> (excluding modal default options, notable: title, footer, remote)</p>
<div class="table-responsive">
<table class="table table-bordered">
<thead>
<tr>
<th>Name</th>
<th>type</th>
<th>default</th>
<th>description</th>
<th>data-*</th>
</tr>
</thead>
<tbody>
<tr>
<td>leftArrow / rightArrow</td>
<td>html</td>
<td><code>&#10094;</code> / <code>&#10095;</code></td>
<td>HTML for the arrows</td>
<td></td>
</tr>
<tr>
<td>wrapping</td>
<td>boolean</td>
<td><code>true</code></td>
<td>Whether the gallery should loop or not</td>
<td></td>
</tr>
<tr>
<td>width / height</td>
<td>integer</td>
<td></td>
<td>Force the width / height</td>
<td><code>data-(width|height)="[0-9]+"</code></td>
</tr>
<tr>
<td>alwaysShowClose</td>
<td>boolean</td>
<td><code>false</code></td>
<td>Always show the close button, even if no title is present</td>
<td></td>
</tr>
<tr>
<td>loadingMessage</td>
<td>html</td>
<td>A fancy loader</td>
<td>HTML injected for loading</td>
<td></td>
</tr>
<tr>
<td>showArrows</td>
<td>bool</td>
<td>true</td>
<td>Disable the navigation overlay</td>
<td></td>
</tr>
</tbody>
</table>
</div>
<code class="block-code">$(this).ekkoLightbox({
alwaysShowClose: true,
onShown: function() {
console.log('Checking our the events huh?');
},
onNavigate: function(direction, itemIndex)
console.log('Navigating '+direction+'. Current item: '+itemIndex);
}
...
});</code>
<br /><br />
<p>The following options are specified per element.</p>
<div class="table-responsive">
<table class="table table-bordered">
<thead>
<tr>
<th>Name</th>
<th>Description</th>
<th>Example</th>
</tr>
</thead>
<tbody>
<tr>
<td>remote</td>
<td>If you can't/don't want to set the href property of an element</td>
<td><code>data-remote="http://www...."</code></td>
</tr>
<tr>
<td>gallery</td>
<td>For grouping elements</td>
<td><code>data-gallery="gallery-name"</code></td>
</tr>
<tr>
<td>type</td>
<td>Force the lightbox into image/YouTube mode.</td>
<td><code>data-type="(image|youtube|vimeo)"</code></td>
</tr>
<tr>
<td>disable-external-check</td>
<td>Force the lightbox loading into an iframe.</td>
<td><code>data-disable-external-check="(true|false)"</code></td>
</tr>
</tbody>
</table>
</div>
<code class="block-code">&lt;a href=&quot;https://unsplash.it/1200/768.jpg?image=251&quot; data-toggle=&quot;lightbox&quot; data-gallery=&quot;example-gallery&quot; data-type=&quot;image&quot;&gt;
&lt;img src=&quot;https://unsplash.it/600.jpg?image=251&quot; class=&quot;img-fluid&quot;&gt;
&lt;/a&gt;</code>
<h2>Events</h2>
<p>Events can be hooked into, set the the same as options above.</p>
<div class="table-responsive">
<table class="table table-bordered">
<thead>
<tr>
<th>Name</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>onContentLoaded</td>
<td>Fired when content (image/video/remote page etc) has been fully loaded.</td>
</tr>
<tr>
<td>onNavigate</td>
<td>Fired before navigating a gallery.</td>
</tr>
<tr>
<td>onShow/onShown/onHide/onHidden</td>
<td>Inherited from the bootstrap modal.</td>
</tr>
</tbody>
</table>
</div>
<h2>Examples</h2>
<p>Thanks to <a href="https://unsplash.it/">https://unsplash.it/</a> for the images.</p>
<ul>
<li><a href="#single-image">Single Image</a></li>
<li><a href="#image-gallery">Image Gallery</a></li>
<li><a href="#videos">Videos</a></li>
<li><a href="#videos-gallery">Gallery of Videos</a></li>
<li><a href="#mixed-gallery">Mixed gallery</a></li>
<li><a href="#programatically-call">Programmatically call</a></li>
<li><a href="#data-remote">Via <code>data-remote</code></a></li>
<li><a href="#force-type">Force type</a></li>
<li><a href="#hidden-elements">Hidden elements</a></li>
<li><a href="#remote-content">Remote content</a></li>
<li><a href="#no-wrapping">Disable wrapping</a></li>
</ul>
<h3 id="single-image">Single Image</h3>
<p>Note: uses modal plugin title option via <code>data-title</code>, and the custom footer tag using <code>data-footer</code></p>
<div class="row">
<div class="offset-sm-4 col-sm-3" data-code="example-1">
<a href="https://unsplash.it/1200/768.jpg?image=250" data-toggle="lightbox" data-title="A random title" data-footer="A custom footer text">
<img src="https://unsplash.it/600.jpg?image=250" class="img-fluid">
</a>
</div>
</div>
<code class="html" data-code="example-1"></code>
<h3 id="image-gallery">Image Gallery</h3>
<p>Galleries are created by adding the <code>data-gallery</code> attribute.</p>
<div data-code="example-2">
<div class="row">
<div class="offset-md-2 col-md-8">
<div class="row">
<a href="https://unsplash.it/1200/768.jpg?image=251" data-toggle="lightbox" data-gallery="example-gallery" class="col-sm-4">
<img src="https://unsplash.it/600.jpg?image=251" class="img-fluid">
</a>
<a href="https://unsplash.it/1200/768.jpg?image=252" data-toggle="lightbox" data-gallery="example-gallery" class="col-sm-4">
<img src="https://unsplash.it/600.jpg?image=252" class="img-fluid">
</a>
<a href="https://unsplash.it/1200/768.jpg?image=253" data-toggle="lightbox" data-gallery="example-gallery" class="col-sm-4">
<img src="https://unsplash.it/600.jpg?image=253" class="img-fluid">
</a>
</div>
<div class="row">
<a href="https://unsplash.it/1200/768.jpg?image=254" data-toggle="lightbox" data-gallery="example-gallery" class="col-sm-4">
<img src="https://unsplash.it/600.jpg?image=254" class="img-fluid">
</a>
<a href="https://unsplash.it/1200/768.jpg?image=255" data-toggle="lightbox" data-gallery="example-gallery" class="col-sm-4">
<img src="https://unsplash.it/600.jpg?image=255" class="img-fluid">
</a>
<a href="https://unsplash.it/1200/768.jpg?image=256" data-toggle="lightbox" data-gallery="example-gallery" class="col-sm-4">
<img src="https://unsplash.it/600.jpg?image=256" class="img-fluid">
</a>
</div>
</div>
</div>
</div>
<code class="html" data-code="example-2"></code>
<h3 id="image-gallery">Image Gallery</h3>
<p>Galleries are created by adding the <code>data-gallery</code> attribute.</p>
<div data-code="example-2">
<div class="row">
<div class="offset-md-2 col-md-8">
<div class="row">
<a href="https://unsplash.it/1200/768.jpg?image=251" data-toggle="lightbox" data-gallery="example-gallery" class="col-sm-4">
<img src="https://unsplash.it/600.jpg?image=251" class="img-fluid">
</a>
<a href="https://unsplash.it/1200/768.jpg?image=252" data-toggle="lightbox" data-gallery="example-gallery" class="col-sm-4">
<img src="https://unsplash.it/600.jpg?image=252" class="img-fluid">
</a>
<a href="https://unsplash.it/1200/768.jpg?image=253" data-toggle="lightbox" data-gallery="example-gallery" class="col-sm-4">
<img src="https://unsplash.it/600.jpg?image=253" class="img-fluid">
</a>
</div>
<div class="row">
<a href="https://unsplash.it/1200/768.jpg?image=254" data-toggle="lightbox" data-gallery="example-gallery" class="col-sm-4">
<img src="https://unsplash.it/600.jpg?image=254" class="img-fluid">
</a>
<a href="https://unsplash.it/1200/768.jpg?image=255" data-toggle="lightbox" data-gallery="example-gallery" class="col-sm-4">
<img src="https://unsplash.it/600.jpg?image=255" class="img-fluid">
</a>
<a href="https://unsplash.it/1200/768.jpg?image=256" data-toggle="lightbox" data-gallery="example-gallery" class="col-sm-4">
<img src="https://unsplash.it/600.jpg?image=256" class="img-fluid">
</a>
</div>
</div>
</div>
</div>
<code class="html" data-code="example-2"></code>
<h3 id="videos">Videos</h3>
<h4>YouTube</h4>
<p>You can use various YouTube URL formats, the regex used is: <code>/^.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|\&v=)([^#\&\?]*).*/</code></p>
<div data-code="example-3">
<p><a href="https://www.youtube.com/watch?v=dQw4w9WgXcQ" data-toggle="lightbox">Justin Bieber - Love Yourself</a></p>
<p><a href="http://youtu.be/b0jqPvpn3sY" data-toggle="lightbox">Tame Impala - Elephant (using youtu.be link)</a></p>
<p><a href="https://www.youtube.com/watch?v=oyEuk8j8imI&rel=0" data-toggle="lightbox">Justin Bieber - Love Yourself</a> (suppress related videos with <code>&rel=0</code>)</p>
</div>
<code data-code="example-3" data-trim="all"></code>
<h4>Vimeo</h4>
<p>You cannot embed Vimeo videos using the standard url (ie http://vimeo.com/80629469); you must link to the embed source (ie player.vimeo.com/video/80629469). This will mean your link url - if the JavaScript fails, will open the full screen player (try opening the first link below in a new tab); the solution to this is to set the lightbox source directly - the second link below does this.</p>
<div data-code="example-3-b">
<p><a href="http://player.vimeo.com/video/80629469" data-toggle="lightbox">City Lights - from Colin Rich (using embed link)</a></p>
<p><a href="http://vimeo.com/80629469" data-remote="http://player.vimeo.com/video/80629469" data-toggle="lightbox">City Lights - from Colin Rich</a> (with reccommended <code>data-remote</code> setting)</p>
</div>
<code data-code="example-3-b" data-trim="all"></code>
<h4>Instagram</h4>
<p></p>
<div data-code="example-3-c">
<p><a href="http://instagram.com/p/BRCYe_wD9pV/" data-toggle="lightbox" data-title="Plug for our new service">Instagram</a></p>
<p>This also works with photos: <a href="//instagram.com/p/BRCdyxnjBsA/" data-toggle="lightbox">Instagram</a></p>
</div>
<code data-code="example-3-c" data-trim="all"></code>
<h4>Forcing width</h4>
<p>Set the width of the video</p>
<div data-code="example-3-d">
<p><a href="https://www.youtube.com/watch?v=e-ORhEE9VVg" data-toggle="lightbox">Taylor Swift - Blank Space (standard)</a></p>
<p><a href="https://www.youtube.com/watch?v=e-ORhEE9VVg" data-toggle="lightbox" data-width="640">Taylor Swift - Blank Space (640 x 360)</a></p>
<p><a href="https://www.youtube.com/watch?v=e-ORhEE9VVg" data-toggle="lightbox" data-width="1280">Taylor Swift - Blank Space (1280 x 780)</a></p>
</div>
<code data-code="example-3-d" data-trim="all"></code>
<!-- i hope your coworkers think you're listening to some justin and taylor -->
<h3 id="videos-gallery">Gallery of Videos</h3>
<div class="row">
<div class="offset-md-1 col-md-10">
<div class="row" data-code="example-4">
<a href="http://www.youtube.com/watch?v=k6mFF3VmVAs" data-toggle="lightbox" data-gallery="youtubevideos" class="col-sm-4">
<img src="//i1.ytimg.com/vi/yP11r5n5RNg/mqdefault.jpg" class="img-fluid">
</a>
<a href="http://youtu.be/iQ4D273C7Ac" data-toggle="lightbox" data-gallery="youtubevideos" class="col-sm-4">
<img src="//i1.ytimg.com/vi/iQ4D273C7Ac/mqdefault.jpg" class="img-fluid">
</a>
<a href="//www.youtube.com/embed/b0jqPvpn3sY" data-toggle="lightbox" data-gallery="youtubevideos" class="col-sm-4">
<img src="//i1.ytimg.com/vi/b0jqPvpn3sY/mqdefault.jpg" class="img-fluid">
</a>
</div>
</div>
</div>
<code data-code="example-4"></code>
<h3 id="mixed-gallery">Mixed gallery</h3>
<div class="row">
<div class="offset-md-1 col-md-10">
<div class="row flex-items-xs-center" data-code="example-5">
<a href="http://www.youtube.com/watch?v=k6mFF3VmVAs" data-toggle="lightbox" data-gallery="mixedgallery" class="col-sm-4">
<img src="//i1.ytimg.com/vi/yP11r5n5RNg/mqdefault.jpg" class="img-fluid">
</a>
<a href="https://unsplash.it/1200/768.jpg?image=257" data-toggle="lightbox" data-gallery="mixedgallery" class="col-sm-4">
<img src="https://unsplash.it/600.jpg?image=257" class="img-fluid">
</a>
<a href="http://vimeo.com/80629469" data-remote="http://player.vimeo.com/video/80629469" data-toggle="lightbox" data-gallery="mixedgallery" class="col-sm-4">
<img src="//b.vimeocdn.com/ts/458/070/458070637_200.jpg" class="img-fluid">
</a>
</div>
</div>
</div>
<code data-code="example-5"></code>
<h3 id="programatically-call">Programmatically call</h3>
<p>These two examples are opened via the JavaScript at the bottom of the source.</p>
<div class="row">
<div class="offset-md-1 col-md-10">
<div class="row" data-code="example-6">
<a href="https://unsplash.it/1200/768.jpg?image=258" id="open-image" class="col-sm-4">
<img src="https://unsplash.it/600.jpg?image=258" class="img-fluid">
</a>
<a href="http://youtu.be/iQ4D273C7Ac" id="open-youtube" class="col-sm-4">
<img src="//i1.ytimg.com/vi/iQ4D273C7Ac/mqdefault.jpg" class="img-fluid">
</a>
</div>
</div>
</div>
<code data-code="example-6"></code>
<code class="block-code">$(&#39;#open-image&#39;).click(function (e) {
e.preventDefault();
$(this).ekkoLightbox();
});
$(&#39;#open-youtube&#39;).click(function (e) {
e.preventDefault();
$(this).ekkoLightbox();
});</code>
<h3 id="data-remote">Via <code>data-remote</code></h3>
<p>Neither of these are <code>&lt;a /&gt;</code> tags, so both rely on the <code>data-remote</code> attribute.</p>
<div class="row">
<div class="offset-md-1 col-md-10">
<div class="row" data-code="example-7" style="height:200px">
<img src="https://unsplash.it/600.jpg?image=259" data-toggle="lightbox" data-remote="https://unsplash.it/1200/768.jpg?image=259" class="img-fluid col-sm-4">
<img src="//i1.ytimg.com/vi/b0jqPvpn3sY/mqdefault.jpg" data-toggle="lightbox" data-remote="//www.youtube.com/embed/b0jqPvpn3sY" class="img-fluid col-sm-4">
</div>
</div>
</div>
<code data-code="example-7"></code>
<h3 id="force-type">Force type</h3>
<p>If the images you are linking to have no extension, the lightbox cannot detect that is an image; therefore you need to tell the lightbox what <code>data-type</code> it is.</p>
<p>Current allowed types are: <code>['image', 'youtube', 'vimeo', 'instagram', 'video', 'url']</code></p>
<div data-code="example-8">
<p><a href="https://unsplash.it/1200/768?image=260" data-title="Force image display" data-footer="The remote of this modal has no extension (https://unsplash.it/1200/768?image=260) but works because the type is forced." data-toggle="lightbox" data-type="image">Click here for an image, but with no extension.</a></p>
<p><a href="https://unsplash.it/1200/768?image=261" data-footer="Without the type forced, the lightbox will remote load the content" data-toggle="lightbox">This link is missing the type attribute, and will iframe the image.</a></p>
<p><a href="http://www.youtube.com/watch?v=b0jqPvpn3sY" data-toggle="lightbox" data-type="image">This link is linking to a YouTube video, but forcing an image.</a></p>
</div>
<code data-code="example-8"></code>
<h3 id="hidden-elements">Hidden elements</h3>
<p>Facebook style, only show a few images but have a large gallery</p>
<div class="row">
<div class="offset-md-2 col-md-8">
<div class="row" data-code="example-9">
<a href="https://unsplash.it/1200/768.jpg?image=263" data-toggle="lightbox" data-gallery="hidden-images" class="col-sm-4">
<img src="https://unsplash.it/600.jpg?image=263" class="img-fluid">
</a>
<a href="https://unsplash.it/1200/768.jpg?image=264" data-toggle="lightbox" data-gallery="hidden-images" class="col-sm-4">
<img src="https://unsplash.it/600.jpg?image=264" class="img-fluid">
</a>
<a href="https://unsplash.it/1200/768.jpg?image=265" data-toggle="lightbox" data-gallery="hidden-images" class="col-sm-4">
<img src="https://unsplash.it/600.jpg?image=265" class="img-fluid">
</a>
<!-- elements not showing, use data-remote -->
<div data-toggle="lightbox" data-gallery="hidden-images" data-remote="https://unsplash.it/1200/768.jpg?image=264" data-title="Hidden item 1"></div>
<div data-toggle="lightbox" data-gallery="hidden-images" data-remote="//www.youtube.com/embed/b0jqPvpn3sY" data-title="Hidden item 2"></div>
<div data-toggle="lightbox" data-gallery="hidden-images" data-remote="https://unsplash.it/1200/768.jpg?image=265" data-title="Hidden item 3"></div>
<div data-toggle="lightbox" data-gallery="hidden-images" data-remote="https://unsplash.it/1200/768.jpg?image=266" data-title="Hidden item 4"></div>
<div data-toggle="lightbox" data-gallery="hidden-images" data-remote="https://unsplash.it/1200/768.jpg?image=267" data-title="Hidden item 5"></div>
</div>
</div>
</div>
<code data-code="example-9"></code>
<h3 id="remote-content">Remote content</h3>
<p>Given a URL, that is not an image or video (including unforced types), load the content using an iFrame.</p>
<div class="row">
<div class="offset-md-1 col-md-10" data-code="example-10">
<div class="row">
<p class="col-sm-3"><a href="http://getbootstrap.com" data-title="Bootstrap" data-width="1200" data-toggle="lightbox" data-gallery="remoteload">Bootstrap Docs</a></p>
</div>
</div>
</div>
<code data-code="example-10"></code>
<h3 id="no-wrapping">Disable wrapping</h3>
<p>To disable wrapping, set `wrapping` to false when creating a gallery.</p>
<div>
<div class="row">
<div class="offset-md-2 col-md-8">
<div class="row">
<a href="https://unsplash.it/1200/768.jpg?image=251" data-toggle="lightbox" data-gallery="example-gallery-11" class="col-sm-4">
<img src="https://unsplash.it/600.jpg?image=251" class="img-fluid">
</a>
<a href="https://unsplash.it/1200/768.jpg?image=252" data-toggle="lightbox" data-gallery="example-gallery-11" class="col-sm-4">
<img src="https://unsplash.it/600.jpg?image=252" class="img-fluid">
</a>
<a href="https://unsplash.it/1200/768.jpg?image=253" data-toggle="lightbox" data-gallery="example-gallery-11" class="col-sm-4">
<img src="https://unsplash.it/600.jpg?image=253" class="img-fluid">
</a>
</div>
<div class="row">
<a href="https://unsplash.it/1200/768.jpg?image=254" data-toggle="lightbox" data-gallery="example-gallery-11" class="col-sm-4">
<img src="https://unsplash.it/600.jpg?image=254" class="img-fluid">
</a>
<a href="https://unsplash.it/1200/768.jpg?image=255" data-toggle="lightbox" data-gallery="example-gallery-11" class="col-sm-4">
<img src="https://unsplash.it/600.jpg?image=255" class="img-fluid">
</a>
<a href="https://unsplash.it/1200/768.jpg?image=256" data-toggle="lightbox" data-gallery="example-gallery-11" class="col-sm-4">
<img src="https://unsplash.it/600.jpg?image=256" class="img-fluid">
</a>
</div>
</div>
</div>
</div>
<code class="html" data-code>$(this).ekkoLightbox({ wrapping: false });</code>
<p class="footer"><span>Built by me, <a href="https://ashleyd.ws">ashleydw</a></span></p>
</div>
</div>
</div>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/3.0.0/jquery.min.js" integrity="sha384-THPy051/pYDQGanwU6poAc/hOdQxjnOEXzbT+OuUAFqNqFjL+4IGLBgCJC3ZOShY" crossorigin="anonymous"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/tether/1.2.0/js/tether.min.js" integrity="sha384-Plbmg8JY28KFelvJVai01l8WyZzrYWG825m+cZ0eDDS1f7d/js6ikvy1+X+guPIB" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/js/bootstrap.min.js"></script>
<script src="../dist/ekko-lightbox.js"></script>
<!-- for documentation only -->
<script src="//cdnjs.cloudflare.com/ajax/libs/anchor-js/3.2.1/anchor.min.js"></script>
<script type="text/javascript">
$(document).ready(function ($) {
// delegate calls to data-toggle="lightbox"
$(document).on('click', '[data-toggle="lightbox"]:not([data-gallery="navigateTo"]):not([data-gallery="example-gallery-11"])', function(event) {
event.preventDefault();
return $(this).ekkoLightbox({
onShown: function() {
if (window.console) {
return console.log('Checking our the events huh?');
}
},
onNavigate: function(direction, itemIndex) {
if (window.console) {
return console.log('Navigating '+direction+'. Current item: '+itemIndex);
}
}
});
});
// disable wrapping
$(document).on('click', '[data-toggle="lightbox"][data-gallery="example-gallery-11"]', function(event) {
event.preventDefault();
return $(this).ekkoLightbox({
wrapping: false
});
});
//Programmatically call
$('#open-image').click(function (e) {
e.preventDefault();
$(this).ekkoLightbox();
});
$('#open-youtube').click(function (e) {
e.preventDefault();
$(this).ekkoLightbox();
});
// navigateTo
$(document).on('click', '[data-toggle="lightbox"][data-gallery="navigateTo"]', function(event) {
event.preventDefault();
return $(this).ekkoLightbox({
onShown: function() {
this.modal().on('click', '.modal-footer a', function(e) {
e.preventDefault();
this.navigateTo(2);
}.bind(this));
}
});
});
/**
* Documentation specific - ignore this
*/
anchors.options.placement = 'left';
anchors.add('h3');
$('code[data-code]').each(function() {
var $code = $(this),
$pair = $('div[data-code="'+$code.data('code')+'"]');
$code.hide();
var text = $code.text($pair.html()).html().trim().split("\n");
var indentLength = text[text.length - 1].match(/^\s+/)
indentLength = indentLength ? indentLength[0].length : 24;
var indent = '';
for(var i = 0; i < indentLength; i++)
indent += ' ';
if($code.data('trim') == 'all') {
for (var i = 0; i < text.length; i++)
text[i] = text[i].trim();
} else {
for (var i = 0; i < text.length; i++)
text[i] = text[i].replace(indent, ' ').replace(' ', '');
}
text = text.join("\n");
$code.html(text).show();
});
});
</script>
</body>
</html>
+47
View File
@@ -0,0 +1,47 @@
{
"name": "ekko-lightbox",
"description": "A lightbox gallery plugin for Bootstrap based on the modal plugin",
"version": "5.2.0",
"keywords": [
"lightbox",
"gallery",
"bootstrap",
"jquery",
"modal"
],
"homepage": "https://github.com/ashleydw/lightbox",
"author": "ashleydw <hello@ashleyd.ws>",
"main": "dist/ekko-lightbox.min.js",
"style": "dist/ekko-lightbox.css",
"less": "ekko-lightbox.less",
"repository": {
"type": "git",
"url": "https://github.com/ashleydw/lightbox.git"
},
"bugs": {
"url": "https://github.com/ashleydw/lightbox/issues"
},
"license": "MIT",
"devDependencies": {
"autoprefixer": "^6.4.0",
"babel-preset-es2015": "^6.13.2",
"cssnano": "^3.7.4",
"grunt": "^0.4.5",
"grunt-babel": "^5.0.0",
"grunt-contrib-cssmin": "^1.0.2",
"grunt-contrib-less": "^1.4.0",
"grunt-contrib-uglify": "^0.11.0",
"grunt-contrib-watch": "^0.6.1",
"grunt-postcss": "^0.8.0",
"grunt-stamp": "^0.3.0"
},
"npmName": "ekko-lightbox",
"npmFileMap": [
{
"basePath": "/dist/",
"files": [
"*"
]
}
]
}
File diff suppressed because it is too large Load Diff