/**
* @package CeraBox
*
* @author Sven & JSK
* @since 27-09-2014
* @version 1.5
*
*/
(function(window){ "use strict";
window.CeraBox = new Class({
version: '1.5',
Implements: [Options],
boxWindow: null,
collection: [],
currentItem: 0,
options: {
ajax: null,
group: true,
width: null,
height: null,
displayTitle: true,
fullSize: false, // Does not effect mobile view
displayOverlay: true, // Does not effect mobile view
clickToClose: false,
loaderAtItem: false,
lang: {
lewo: 'Poprzednie zdjęcie',
prawo: 'Następne zdjęcie',
zamknij: 'Zamknij okno'
},
animation: 'fade',
errorLoadingMessage: 'The requested content cannot be loaded or might not be supported. Please try again later.',
titleFormat: 'Item {number} / {total} {title}',
addContentProtectionLayer: false,
mobileView: Browser.platform == 'ios' ? 1 : 0 || Browser.platform == 'android' ? 1 : 0 || Browser.platforma == 'webos' ? 1 : 0,
fixedPosition: false,
clickToCloseOverlay: true,
constrainProportions: false,
devicePixelRatio: window.devicePixelRatio!==undefined ? window.devicePixelRatio : 1,
preventScrolling: false,
events: {
onOpen: function(currentItem, collection){},
onChange: function(currentItem, collection){},
onClose: function(currentItem, collection){},
onAnimationEnd: function(currentItem, collection){}
}
},
/**
* Initialization add items to the box
*
* @param elements collection
* @param options {
* ajax: {},
* group: bool,
* width: int,
* height: int,
* displayTitle: bool,
* fullSize: bool,
* displayOverlay: bool,
* clickToClose: bool,
* loaderAtItem: bool,
* animation: 'fade'|'ease',
* errorLoadingMessage: string,
* titleFormat: string,
* addContentProtectionLayer: bool,
* mobileView: bool,
* fixedPosition: bool,
* clickToCloseOverlay: bool,
* constrainProportions: bool,
* devicePixelRatio: int,
* preventScrolling: bool,
* events: {
* onOpen: function(currentItem, collection){},
* onChange: function(currentItem, collection){},
* onClose: function(currentItem, collection){},
* onAnimationEnd: function(currentItem, collection){}
* }
* }
*/
initialize: function(elements, options) {
this.boxWindow = CeraBoxWindow;
elements = $$(elements);
if (options && typeOf(options.group)!='null' && options.group===false && elements.length>1) {
elements.each(function(item){
item.store('cerabox', new CeraBox(item, options));
});
}
//set options
this.setOptions(options);
// Handle the passed elements
elements.each(function(item, index) {
// Add to collection
this.collection[index] = item;
// Force handling type
var type = item.dataset ? // dataset supported
(typeOf(item.dataset.type)=='string' && item.dataset.type.trim()!='' ? item.dataset.type.trim() : null) :
(item.get('data-type') && item.get('data-type').trim()!='' ? item.get('data-type').trim() : null);
if ((null!==this.options.ajax && type===null) || type=='ajax') {
item.addEvent('click', function(event){
if (this._itemClick(event)) {
this.currentItem = index;
this.showAjax();
return true;
}
return false;
}.bind(this));
}
else if ((item.get('href').test(/^#/i) && type===null) || type=='inline') {
item.addEvent('click', function(event){
if (this._itemClick(event)) {
this.currentItem = index;
this.showInline();
return true;
}
return false;
}.bind(this));
}
else if ((item.get('href').test(/\.(jpg|jpeg|png|gif|bmp|webp)(.*)?$/i) && type===null) || type=='image') {
item.addEvent('click', function(event){
if (this._itemClick(event)) {
this.currentItem = index;
this.showImage();
return true;
}
return false;
}.bind(this));
}
else {
if (type!==null && type!='iframe') {
throw 'Unknown type in dataset: ' + type;
}
item.addEvent('click', function(event){
if (this._itemClick(event)) {
this.currentItem = index;
this.showIframe();
return true;
}
return false;
}.bind(this));
}
}.bind(this));
},
/**
* Display AJAX item
*/
showAjax: function() {
var ceraBox = this,
currentItem = ceraBox.collection[ceraBox.currentItem],
requestEr = new Request.HTML(Object.merge({
url: currentItem.get('href'),
method: 'post',
data: '',
evalScripts: false,
onSuccess: function(responseTree, responseElements, responseHTML, responseJavaScript) {
if (false===ceraBox.boxWindow.getBusy())
return;
// pre load images
var assets = [];
Array.each(responseElements, function(ele){
if(ele.get('tag')=='img' && ele.get('src')) {
assets.append([ele.get('src')]);
}
});
var assetsLoaded = function(){
var ajaxEle = ceraBox.boxWindow.preLoadElement(responseTree);
// Check if size needs to be constrained
if( true===ceraBox.options.constrainProportions &&
!(ceraBox.options.width && ceraBox.options.height) &&
(ceraBox.options.width || ceraBox.options.height)
){
if (ceraBox.options.width) {
ajaxEle.set('height', Math.round(ajaxEle.getScrollSize().y * (ceraBox.boxWindow.sizeStringToInt(ceraBox.options.width, 'x') / ajaxEle.getScrollSize().x) ));
ajaxEle.set('width', ceraBox.options.width);
} else {
ajaxEle.set('width', Math.round(ajaxEle.getScrollSize().x * (ceraBox.boxWindow.sizeStringToInt(ceraBox.options.height, 'y') / ajaxEle.getScrollSize().y) ));
ajaxEle.set('height', ceraBox.options.height);
}
}
else {
ajaxEle.setStyle('width', ceraBox.options.width?ceraBox.options.width:ajaxEle.getScrollSize().x);
ajaxEle.setStyle('height', ceraBox.options.height?ceraBox.options.height:ajaxEle.getScrollSize().y);
}
var dimension = ceraBox.boxWindow.getSizeElement(ajaxEle);
ajaxEle = ajaxEle.get('html');
ceraBox.boxWindow.onLoad(dimension.width, dimension.height)
.addEvent('complete', function(){
this.removeEvents('complete');
if (false===ceraBox.boxWindow.getBusy())
return;
if (false!==ceraBox.options.displayTitle)
ceraBox.boxWindow.displayTitle((currentItem.get('title')?currentItem.get('title'):''), ceraBox.currentItem+1, ceraBox.collection.length);
ceraBox.boxWindow.setContent(new Element('div', {'html':ajaxEle}))
.openWindow();
// Run script from response
(function(){eval(responseJavaScript)}).call(ceraBox);
});
};
if (assets.length)
Asset.images(assets, {
onComplete: assetsLoaded
});
else
assetsLoaded();
},
onerror: ceraBox._timedOut.bind(ceraBox),
onTimeout: ceraBox._timedOut.bind(ceraBox),
onFailure: ceraBox._timedOut.bind(ceraBox),
onException: ceraBox._timedOut.bind(ceraBox)
}, typeOf(ceraBox.options.ajax)==='object'?ceraBox.options.ajax:{})).send();
},
/**
* Display Inline item
*/
showInline: function() {
var ceraBox = this,
currentItem = ceraBox.collection[ceraBox.currentItem],
inlineEle = (currentItem.get('href').test(/^#\$/i) && typeOf(window[currentItem.get('href').replace(/^#\$/i,'')])!='null')
? ((typeOf(window[currentItem.get('href').replace(/^#\$/i,'')])!='element') ? new Element('div',{'html':window[currentItem.get('href').replace(/^#\$/i,'')]}) : window[currentItem.get('href').replace(/^#\$/i,'')])
: (document.id(document.body).getElement(currentItem.get('href')) ? document.id(document.body).getElement(currentItem.get('href')).clone() : null);
if (null!==inlineEle) {
// pre load images
var assets = [];
Array.each(inlineEle.getElements('img'), function(ele){
if(ele.get('src')) {
assets.append([ele.get('src')]);
}
});
var assetsLoaded = function(){
var inlineEleClone = ceraBox.boxWindow.preLoadElement(inlineEle.clone());
// Check if size needs to be constrained
if( true===ceraBox.options.constrainProportions &&
!(ceraBox.options.width && ceraBox.options.height) &&
(ceraBox.options.width || ceraBox.options.height)
){
if (ceraBox.options.width) {
inlineEleClone.set('height', Math.round(inlineEleClone.getSize().y * (ceraBox.boxWindow.sizeStringToInt(ceraBox.options.width, 'x') / inlineEleClone.getScrollSize().x) ));
inlineEleClone.set('width', ceraBox.options.width);
} else {
inlineEleClone.set('width', Math.round(inlineEleClone.getScrollSize().x * (ceraBox.boxWindow.sizeStringToInt(ceraBox.options.height, 'y') / inlineEleClone.getSize().y) ));
inlineEleClone.set('height', ceraBox.options.height);
}
}
else {
inlineEleClone.setStyle('width', ceraBox.options.width?ceraBox.options.width:inlineEleClone.getScrollSize().x);
inlineEleClone.setStyle('height', ceraBox.options.height?ceraBox.options.height:inlineEleClone.getSize().y);
}
var dimension = ceraBox.boxWindow.getSizeElement(inlineEleClone);
ceraBox.boxWindow.onLoad(dimension.width, dimension.height)
.addEvent('complete', function(){
this.removeEvents('complete');
if (false===ceraBox.boxWindow.getBusy())
return;
if (false!==ceraBox.options.displayTitle)
ceraBox.boxWindow.displayTitle((currentItem.get('title')?currentItem.get('title'):''), ceraBox.currentItem+1, ceraBox.collection.length);
ceraBox.boxWindow.setContent(inlineEle)
.openWindow();
});
};
if (assets.length)
Asset.images(assets, {
onComplete: assetsLoaded
});
else
assetsLoaded();
}
else {
ceraBox._timedOut();
}
},
/**
* Display image item
*/
showImage: function() {
var ceraBox = this,
currentItem = ceraBox.collection[ceraBox.currentItem],
image = new Asset.image(currentItem.get('href'), {
'class': 'ceraImage',
onload: function() {
if (false===ceraBox.boxWindow.getBusy())
return;
// Check if size needs to be constrained
if( true===ceraBox.options.constrainProportions &&
!(ceraBox.options.width && ceraBox.options.height) &&
(ceraBox.options.width || ceraBox.options.height)
){
if (ceraBox.options.width) {
this.set('height', Math.round(this.get('height').toInt() * (ceraBox.boxWindow.sizeStringToInt(ceraBox.options.width, 'x') / this.get('width')) ));
this.set('width', ceraBox.options.width);
} else {
this.set('width', Math.round(this.get('width').toInt() * (ceraBox.boxWindow.sizeStringToInt(ceraBox.options.height, 'y') / this.get('height')) ));
this.set('height', ceraBox.options.height);
}
}
else {
this.set('width', ceraBox.options.width?ceraBox.options.width:this.get('width'));
this.set('height', ceraBox.options.height?ceraBox.options.height:this.get('height'));
}
var dimension = ceraBox.boxWindow.getSizeElement(this);
// HDPI screens
if (ceraBox.options.devicePixelRatio > 1)
dimension = {
width: dimension.width / ceraBox.options.devicePixelRatio,
height: dimension.height / ceraBox.options.devicePixelRatio
};
ceraBox.boxWindow.setZoom(1);
ceraBox.boxWindow.onLoad(dimension.width, dimension.height)
.addEvent('complete', function(){
this.removeEvents('complete');
if (false===ceraBox.boxWindow.getBusy())
return;
if (false!==ceraBox.options.displayTitle)
ceraBox.boxWindow.displayTitle((currentItem.get('title')?currentItem.get('title'):''), ceraBox.currentItem+1, ceraBox.collection.length);
ceraBox.boxWindow.setContent(image)
.openWindow();
cerabox.getElement('.cerabox-zoomIn').addEvent('click',function(event){event.stop(); ceraBox.boxWindow.zoomIn(image);}).setStyle('display','block');
cerabox.getElement('.cerabox-zoomOut').addEvent('click',function(event){event.stop(); ceraBox.boxWindow.zoomOut(image);}).setStyle('display','block');
});
},
onerror: ceraBox._timedOut.bind(ceraBox)
});
},
/**
* Display iframe item
*/
showIframe: function() {
// Set timeout timer incase request cannot be done
this.boxWindow.setTimeOuter(this._timedOut.delay(10000, this));
var ceraBox = this,
currentItem = ceraBox.collection[ceraBox.currentItem],
ceraIframe = new IFrame({
src: currentItem.get('href'),
'class': 'ceraIframe',
styles: {
width: 1,
height: 1,
border: '0px'
},
events: {
load: function() {
if (false===ceraBox.boxWindow.getBusy() && !ceraBox.boxWindow.getWindowOpen())
return;
// No fixed set size try to add onBeforeUnload function
if (!ceraBox.options.width && !ceraBox.options.height)
try {
if (!Browser.name == 'ie' || Browser.version > 8)
this.contentWindow.onbeforeunload = function(){
ceraBox.boxWindow.loading(ceraBox);
this.setStyles({
'width': '1px',
'height': '1px'
});
}.bind(this);
else
this.setStyles({
'width': '1px',
'height': '1px'
});
}
catch(err) {}
if (ceraBox.options.width)
this.setStyle('width', ceraBox.options.width);
if (ceraBox.options.height)
this.setStyle('height', ceraBox.options.height);
var dimension = ceraBox.boxWindow.getSizeElement(this);
ceraBox.boxWindow.onLoad(dimension.width, dimension.height)
.addEvent('complete', function(){
this.removeEvents('complete');
if (false===ceraBox.boxWindow.getBusy() && !ceraBox.boxWindow.getWindowOpen())
return;
//if (false!==ceraBox.options.displayTitle)
//ceraBox.boxWindow.displayTitle((currentItem.get('title')?currentItem.get('title'):''), ceraBox.currentItem+1, ceraBox.collection.length);
ceraBox.boxWindow.openWindow();
ceraIframe.setFocus();
});
}
}
});
ceraIframe.set('border',0);
ceraIframe.set('frameborder',0);
ceraIframe.set('title','iframe');
this.boxWindow.setContent(ceraIframe);
},
/**
* Has timed out display error
*/
_timedOut: function() {
var ceraBox = this,
errorEle = new Element('span',{'class':'cerabox-error','html':ceraBox.options.errorLoadingMessage});
var errorEleClone = ceraBox.boxWindow.preLoadElement(errorEle.clone());
errorEleClone.setStyle('width','270px');
errorEleClone.setStyle('height',errorEleClone.getSize().y + 'px');
if (this.options.mobileView)
errorEle.setStyles({
'position': 'absolute',
'top': '50%',
'margin-top': -Math.round(errorEleClone.getSize().y/2) + 'px'
});
var dimension = ceraBox.boxWindow.getSizeElement(errorEleClone, true);
ceraBox.boxWindow.onLoad(dimension.width, dimension.height)
.addEvent('complete', function(){
this.removeEvents('complete');
if (false===ceraBox.boxWindow.getBusy())
return;
ceraBox.boxWindow.hideTitle();
ceraBox.boxWindow.setContent(errorEle)
.openWindow();
});
},
// Default stuff to do when item clicked
_itemClick: function(event) {
if (event)
event.preventDefault();
if (this.boxWindow.getBusy())
return false;
this.boxWindow.loading(this);
return true;
},
/**
* Simple logging function
*/
_log: function(log, alertIt) {
try {
console.log(log);
}
catch(err) {
if (alertIt)
alert(log);
}
}
});
// View
window.CeraBoxWindow = (function(window) {
var busy = false,
lock = false,
loaderTimer = null,
timeOuter = null,
windowOpen = false,
currentInstance = null,
currentDimension = {x:0, y:0},
currentZoom = 1,
hudTimer = null,
// Touch
startPos = {x:null, y:null},
endPos = {x:null, y:null},
viewport = {x:0, y:0},
cerabox = null;
var boxWindow = new Class({
initialize: function() {
window.addEvent('domready', function(){
// Add html
initHTML();
this.updateWindow();
// Terminate loading
document.id('cerabox-loading').addEvent('click', function(event){
event.stop();
this.close(true);
}.bind(this));
// Keyboard controls
document.addEvent('keyup', function(event) {
if (event.key == 'esc')
this.close();
if (event.target.get('tag')=='input' || event.target.get('tag')=='select' || event.target.get('tag')=='textarea')
return;
if (event.key == 'left')
cerabox.getElement('.cerabox-left').fireEvent('click', event);
if (event.key == 'right')
cerabox.getElement('.cerabox-right').fireEvent('click', event);
}.bind(this));
// Touch controls
cerabox.addEvent('touchstart', touchStart);
cerabox.addEvent('touchmove', touchMove);
cerabox.addEvent('touchend', touchEnd);
cerabox.addEvent('touchcancel', touchCancel);
// No movement on the loader
document.id('cerabox-loading').addEvent('touchmove',function(event){event.stop()});
}.bind(this));
window.addEvent('resize', this.updateWindow.bind(this));
window.addEvent('scroll', this.updateWindow.bind(this, 'scroll'));
window.addEvent('orientationchange', this.updateWindow.bind(this));
},
updateWindow: function(type) {
this.setViewport();
// Window not open no need to update further
if (!windowOpen || null===currentInstance || busy || (type=='scroll' && !currentInstance.options.mobileView)) {
return;
}
busy = true;
if (false!==currentInstance.options.displayOverlay || currentInstance.options.mobileView) {
displayOverlay();
}
transformItem()
.addEvent('complete', function(){
this.removeEvents('complete');
showHud();
busy = false;
});
},
close: function(terminate) {
if ((busy && !terminate) || lock || !currentInstance)
return;
busy = !terminate;
// Prevent Scrolling
if (true===currentInstance.options.preventScrolling)
preventScrolling(false);
clearInterval(timeOuter);
clearInterval(loaderTimer);
clearInterval(hudTimer);
document.id('cerabox-loading').setStyle('display', 'none');
if (currentInstance.options.mobileView) {
document.id('cerabox-background').setStyles({
'display':'none',
'width': 0,
'height': 0,
'opacity': 0
});
cerabox.setStyles({
'display':'none'
});
cerabox.getElement('.cerabox-content').empty().setStyles({
'opacity': 0,
'transform': ''
});
cerabox.getElement('.cerabox-zoomIn').removeEvents('click').setStyle('display','none');
cerabox.getElement('.cerabox-zoomOut').removeEvents('click').setStyle('display','none');
cerabox.getElement('.cerabox-left').removeEvents('click').setStyle('display','none');
cerabox.getElement('.cerabox-right').removeEvents('click').setStyle('display','none');
this.hideTitle();
if (windowOpen){
currentInstance.options.events.onClose.call(
currentInstance,
currentInstance.collection[currentInstance.currentItem],
currentInstance.collection
);
}
currentInstance = null;
windowOpen = false;
busy = false;
}
else {
cerabox.set('tween', {duration: 50}).tween('opacity', 0).get('tween')
.addEvent('complete', function() {
this.removeEvents('complete');
document.id('cerabox-background').set('tween', {duration: 50,link:'chain'}).tween('opacity',0)
.get('tween')
.addEvent('chainComplete', function() {
this.removeEvents('chainComplete');
document.id('cerabox-background').setStyle('display', 'none');
cerabox.setStyles({
'display':'none'
});
cerabox.getElement('.cerabox-content').empty().setStyles({
'opacity': 0,
'transform': ''
});
cerabox.getElement('.cerabox-zoomIn').removeEvents('click').setStyle('display','none');
cerabox.getElement('.cerabox-zoomOut').removeEvents('click').setStyle('display','none');
cerabox.getElement('.cerabox-left').removeEvents('click').setStyle('display','none');
cerabox.getElement('.cerabox-right').removeEvents('click').setStyle('display','none');
_instance.hideTitle();
if (windowOpen){
currentInstance.options.events.onClose.call(
currentInstance,
currentInstance.collection[currentInstance.currentItem],
currentInstance.collection
);
}
currentInstance = null;
windowOpen = false;
busy = false;
});
});
}
},
setZoom(i) {
currentZoom = 1;
},
zoomIn(img) {
currentZoom = currentZoom+0.2;
img.removeEvents();
img.setStyle('cursor', 'grab');
var startX = 0;
var startY = 0;
var xX = 0;
var yY = 0;
var myDrag = new Drag(img, {
onDrag: function(el,e){
if (!startX) {
startX = e.client.x;
startY = e.client.y;
} else {
var xa = -startX + e.client.x+xX;
var ya = -startY + e.client.y+yY;
img.setStyle('transform','matrix('+currentZoom+',0,0,'+currentZoom+','+xa+','+ya+')');
}
},
onComplete: function(el,e) {
xX = -startX + e.client.x+xX;
yY = -startY + e.client.y+yY;
startX = 0;
startY = 0;
}
});
img.setStyle('transform','matrix('+currentZoom+',0,0,'+currentZoom+',0,0)');
currentZoom = currentZoom;
},
zoomOut(img) {
currentZoom = (currentZoom > 1) ? currentZoom-0.2 : 1;
img.setStyle('transform','matrix('+currentZoom+',0,0,'+currentZoom+',0,0)');
currentZoom = currentZoom;
},
/**
* Set content with element
* @param element
* @return CeraBoxWindow
*/
setContent: function(element) {
cerabox.getElement('.cerabox-content')
.empty()
//.setStyle('opacity',0)
.adopt(element);
return this;
},
/**
* Set current cerabox and ready window
* @param instance CeraBox
* @return CeraBoxWindow
*/
loading: function(instance) {
if (!instanceOf(instance, CeraBox))
throw 'Instance should be an instance of CeraBox';
this.setViewport();
currentInstance = instance;
busy = true;
// Protection
cerabox.getElement('.cerabox-content-protection').setStyle('display','none');
if (true===currentInstance.options.addContentProtectionLayer)
cerabox.getElement('.cerabox-content-protection').setStyle('display','block');
// Click to close
cerabox.setStyle('cursor','auto').removeEvents('click');
if (true===currentInstance.options.clickToClose)
cerabox.setStyle('cursor','pointer').addEvent('click', function(event){event.stop(); this.close();}.bind(this));
// Prevent Scrolling
if (true===currentInstance.options.preventScrolling)
preventScrolling(true);
// Make sure it doesn't time out when started a new request and prev loader is gone
clearInterval(timeOuter);
clearInterval(loaderTimer);
document.id('cerabox-loading').setStyle('display', 'none');
loaderTimer = displayLoader.delay(200);
// Mobile view
cerabox.removeClass('mobile');
if (currentInstance.options.mobileView) {
cerabox.addClass('mobile');
}
return this;
},
/**
* Adopt element to preloading element
* @param element
* @return element preloaded element
*/
preLoadElement: function(element) {
cerabox.setStyle('display','block');
return cerabox.getElement('#cerabox-ajaxPreLoader').empty().adopt(element);
},
/**
* Ready the window for new content
* @param width
* @param height
* @return tween
*/
onLoad: function(width, height) {
// Lock window
lock = true;
clearInterval(timeOuter);
clearInterval(loaderTimer);
if (false!==currentInstance.options.displayOverlay || currentInstance.options.mobileView) {
displayOverlay();
}
// Clear preloader
cerabox.getElement('#cerabox-ajaxPreLoader').empty().setStyles({'width':'auto','height':'auto'});
currentDimension = {
x: width,
y: height
};
return cerabox.getElement('.cerabox-content').set('tween', {duration: currentInstance.options.mobileView?0:300})
.tween('opacity', (windowOpen && cerabox.getElement('.cerabox-content iframe.ceraIframe')?1:0))
.get('tween');
},
/**
* Open cerabox window
* @param width
* @param height
*/
openWindow: function(width, height) {
// Hide loader
document.id('cerabox-loading').setStyle('display', 'none');
width = currentDimension.x = width || currentDimension.x;
height = currentDimension.y = height || currentDimension.y;
var currentItem = currentInstance.collection[currentInstance.currentItem];
showHud();
if (windowOpen) {
transformItem(width, height);
if (currentInstance.options.mobileView) {
cerabox.getElement('.cerabox-content').setStyle('opacity',1);
// unlock window
lock = false;
busy = false;
addNavButtons();
// onChange event
currentInstance.options.events.onChange.call(currentInstance, currentItem, currentInstance.collection);
}
else {
cerabox.getElement('.cerabox-content')
.set('tween', {duration: cerabox.getElement('.cerabox-content iframe.ceraIframe')?0:200}).tween('opacity',1)
.get('tween')
.addEvent('complete', function(){
this.removeEvents('complete');
// unlock window
lock = false;
busy = false;
addNavButtons();
// onChange event
currentInstance.options.events.onChange.call(currentInstance, currentItem, currentInstance.collection);
});
}
return;
}
if (!currentInstance.options.mobileView)
cerabox.getElement('.cerabox-content').setStyle('opacity', 1);
// onOpen event
currentInstance.options.events.onOpen.call(currentInstance, currentItem, currentInstance.collection);
transformItem(width, height).addEvent('complete', function(){
this.removeEvents('complete');
// If mobile view display content when window is rdy
if (currentInstance.options.mobileView)
cerabox.getElement('.cerabox-content').setStyle('opacity', 1);
// unlock window
lock = false;
busy = false;
addNavButtons();
// onChange event
currentInstance.options.events.onAnimationEnd.call(currentInstance, currentItem, currentInstance.collection);
});
currentItem.blur();
cerabox.setFocus();
windowOpen = true;
},
/**
* Display title
* @param text string
* @param number int
* @param total int
* @return CeraBoxWindow
*/
displayTitle: function(text, number, total) {
if (total>1) {
text = currentInstance.options.titleFormat.substitute({
'number': number,
'total': total,
'title': text
});
}
// Set text if passed else only set display
var titleElement = cerabox.getElement('.cerabox-title span')
if (text) {
titleElement.setStyle('display','block').set('text', text);
titleElement.set('html', titleElement.get('html').replace('\n', '
'));
} else {
titleElement.setStyle('display','none');
}
return this;
},
/**
* Hide title
* @return CeraBoxWindow
*/
hideTitle: function() {
cerabox.getElement('.cerabox-title span')
.setStyle('display','none');
return this;
},
/**
* Set viewport
* @return CeraBoxWindow
*/
setViewport: function() {
viewport = {
x: (window.innerWidth?window.innerWidth:window.getSize().x),
y: (window.innerHeight?window.innerHeight:window.getSize().y)
};
return this;
},
/**
* Getter viewport
*/
getViewport: function() {
return viewport;
},
/**
* Getter currentInstance
* @return CeraBox
*/
getCurrentInstance: function() {
return currentInstance;
},
/**
* Getter busy - lol
* @return bool
*/
getBusy: function() {
return busy;
},
/**
* Getter windowOpen
* @return bool
*/
getWindowOpen: function() {
return windowOpen;
},
/**
* Set timeOuter
* @param timer
* @return CeraBoxWindow
*/
setTimeOuter: function(timer) {
timeOuter = timer;
return this;
},
/**
* Get size element object
*
* @param element
* @return object
*/
getSizeElement: function(element, forceFullSize) {
var eleWidth = 0, eleHeight = 0;
if (element.get('tag')=='iframe') {
cerabox.setStyle('display','block');
try {
eleWidth = (element.get('width')?sizeStringToInt(element.get('width'),'x'):(element.getStyle('width').toInt()>1?sizeStringToInt(element.getStyle('width'),'x'):
(element.contentWindow.document.getScrollSize().x?element.contentWindow.document.getScrollSize().x:viewport.x * 0.75)));
}
catch(err) {
eleWidth = viewport.x * 0.75;
}
try {
eleHeight = (element.get('height')?sizeStringToInt(element.get('height'),'y'):(element.getStyle('height').toInt()>1?sizeStringToInt(element.getStyle('height'),'y'):
(element.contentWindow.document.getScrollSize().y?element.contentWindow.document.getScrollSize().y:viewport.y * 0.75)));
}
catch(err) {
eleHeight = viewport.y * 0.75;
}
/*if (Browser.ie) {
eleHeight = eleHeight + 20;
}*/
if (!forceFullSize && false===currentInstance.options.fullSize) {
if ((viewport.y - 100) cerabox.getSize().x+40 &&*/ viewport.x > width+60) {
morphObject['margin-left'] = Math.round((-width/2) + (!currentInstance.options.fixedPosition?document.id(document.body).getScroll().x:0)) + 'px';
}
else {
morphObject['margin-left'] = Math.round(((viewport.x/2)-width-40) + (!currentInstance.options.fixedPosition?document.id(document.body).getScroll().x:0)) + 'px';
}
if (/*viewport.y > cerabox.getSize().y+40 &&*/ viewport.y > height+40) {
morphObject['margin-top'] = Math.round((-height/2) + (!currentInstance.options.fixedPosition?document.id(document.body).getScroll().y:0)) + 'px';
}
else {
morphObject['margin-top'] = Math.round((-viewport.y/2+20) + (!currentInstance.options.fixedPosition?document.id(document.body).getScroll().y:0)) + 'px';
}
// Reset from mobile if needed
cerabox.getElement('.cerabox-content').setStyles({
'width': '100%',
'height': '100%',
'left': 0,
'top': 0
});
if (!windowOpen) {
switch (currentInstance.options.animation) {
case 'ease':
var currentItem = currentInstance.collection[currentInstance.currentItem];
Object.append(morphObject, {
'top':cerabox.getStyle('top'),
'left':cerabox.getStyle('left')
});
return cerabox.setStyles({
'display':'block',
'left':(currentItem.getPosition().x - (currentInstance.options.fixedPosition?document.id(document.body).getScroll().x:0)) + 'px',
'top':(currentItem.getPosition().y - (currentInstance.options.fixedPosition?document.id(document.body).getScroll().y:0)) + 'px',
'width':currentItem.getSize().x + 'px',
'height':currentItem.getSize().y + 'px',
'margin':0,
'opacity':0
}).set('morph', {duration: 200}).morph(morphObject).get('morph');
break;
case 'fade':
default:
Object.append(morphObject, {
'opacity':0
});
return cerabox.setStyles(morphObject).set('tween', {duration: 200}).tween('opacity', 1).get('tween');
break;
}
}
else {
return cerabox.set('morph', {duration: 150}).morph(morphObject).get('morph');
}
}
}
/**
* Display overlay
*/
function displayOverlay() {
var styles = {
'display': 'block',
'opacity': currentInstance.options.mobileView?1:.5,
'top': 0,
'left': 0,
'height': '100%',
'width': '100%',
'position': 'fixed'
};
// iOS does not support position fixed
if (currentInstance.options.mobileView) {
Object.merge(styles, {
'top': 0,
'left': 0,
'width': (document.id(document.body).getScrollSize().x) + 'px',
'height': (document.id(document.body).getScrollSize().y) + 'px',
'position': 'absolute'
});
}
document.id('cerabox-background').setStyles(styles);
}
/**
* Display loading spinner
*/
function displayLoader() {
var styles = {
'position': 'fixed',
'display': 'block',
'top': '50%',
'left': '50%',
'margin-top': '-20px',
'margin-left': '-20px',
'-webkit-transform': 'scale(1)',
'transform': 'scale(1)'
};
// loaderAtItem
if (true===currentInstance.options.loaderAtItem && !windowOpen) {
var currentItem = currentInstance.collection[currentInstance.currentItem];
Object.append(styles, {
'position': 'absolute',
'top': Math.round(((currentItem.getSize().y/2) - (document.id('cerabox-loading').getStyle('height').toInt()/2)) + currentItem.getPosition().y) + 'px',
'left': Math.round(((currentItem.getSize().x/2) - (document.id('cerabox-loading').getStyle('width').toInt()/2)) + currentItem.getPosition().x) + 'px',
'margin-top': 0,
'margin-left': 0
});
}
else {
if (currentInstance.options.mobileView) {
var landscape = Math.abs(window.orientation) == 90,
screenWidth = landscape ? screen.height : screen.width;
// Scale loader
Object.append(styles, {
'position': 'absolute',
'top': Math.round(((viewport.y/2) - (document.id('cerabox-loading').getStyle('height').toInt()/2)) + document.id(document.body).getScroll().y) + 'px',
'left': Math.round(((viewport.x/2) - (document.id('cerabox-loading').getStyle('width').toInt()/2)) + document.id(document.body).getScroll().x) + 'px',
'margin-top': 0,
'margin-left': 0,
'-webkit-transform': 'scale(' + (viewport.x / screenWidth) + ')',
'transform': 'scale(' + (viewport.x / screenWidth) + ')'
});
}
}
document.id('cerabox-loading').setStyles(styles);
loaderAnimation();
}
/**
* Loader animation
*
* @param frame int
*/
function loaderAnimation(frame) {
if (!frame)
frame=0;
document.id('cerabox-loading').getElement('div').setStyle('top', (frame * -40) + 'px');
frame = (frame + 1) % 12;
if (document.id('cerabox-loading').getStyle('display')!='none')
loaderAnimation.delay(60, this, frame);
}
/**
* Get the pixels of given element size
*
* @param size string
* @param dimension 'x'|'y'
*
* @return int
*/
function sizeStringToInt(size, dimension) {
return (typeOf(size)=='string' && size.test('%')?viewport[dimension]*(size.toInt()/100):size.toInt());
}
/**
* Inject needed HTML to the body
*/
function initHTML() {
var wrapper = document.id(document.body);
if (!wrapper.getElement('#cerabox')) {
wrapper.adopt([
new Element('div',{'id':'cerabox-loading'}).adopt(new Element('div')),
new Element('div',{'id':'cerabox-background', 'events':{'click':function(event){event.stop();if(currentInstance.options.clickToCloseOverlay)_instance.close()}}}),
cerabox = new Element('div',{'id':'cerabox','role':'dialog','aria-labelledby':'cerabox-title','aria-describedby':'cerabox-content'}).adopt([
new Element('div', {'class':'cerabox-title','id':'cerabox-title'}).adopt(new Element('span')),
new Element('div', {'class':'cerabox-content','id':'cerabox-content','role':'document'}),
new Element('a', {'class':'cerabox-left', 'href':'#'}).adopt(new Element('span').appendText('Previous')),
new Element('a', {'class':'cerabox-right', 'href':'#'}).adopt(new Element('span').appendText('Next')),
new Element('a', {'class':'cerabox-close', 'href':'#', 'events':{
'click':function(event) {event.stop();_instance.close()},
'keyup':function(event) {
if (event.key == 'enter') {
event.stop();
_instance.close();
}
}}}).adopt(new Element('span').appendText('Close')),
new Element('a', {'class':'cerabox-zoomIn', 'href':'#'}).setStyle('display','none').adopt(new Element('span').appendText('ZoomIn')),
new Element('a', {'class':'cerabox-zoomOut', 'href':'#'}).setStyle('display','none').adopt(new Element('span').appendText('ZoomOut')),
new Element('div', {'class':'cerabox-content-protection'}),
new Element('div', {'id':'cerabox-ajaxPreLoader','styles':{'float':'left','overflow':'hidden','display':'block'}})
]),
]);
}
}
/**
* Hide title and buttons
*/
function hideHud() {
clearInterval(hudTimer);
cerabox.getElements('.cerabox-title, .cerabox-close, .cerabox-left, .cerabox-right').set('tween', {duration: 500}).tween('opacity', 0);
}
/**
* Show title and buttons
*/
function showHud() {
cerabox.getElements('.cerabox-title, .cerabox-close, .cerabox-left, .cerabox-right').setStyle('opacity',1);
clearInterval(hudTimer);
if (currentInstance.options.mobileView &&
!currentInstance.options.clickToClose &&
'createTouch' in document &&
!cerabox.getElement('.cerabox-content iframe.ceraIframe')
) {
hudTimer = hideHud.delay(5000);
}
}
/**
* Touch events
*/
function touchStart(event) {
startPos = endPos = event.client;
}
function touchMove(event) {
endPos = event.client;
event.preventDefault();
}
function touchEnd(event) {
// Make sure it should only fire on end
if (null!==startPos.x && null!==endPos.x) {
var distance = getTouchDistance(),
landscape = Math.abs(window.orientation) == 90,
screenWidth = landscape ? screen.height : screen.width;
// Far enough on scale
if (50 <= Math.round(distance * (screenWidth / viewport.x))) {
fireTouchEvent(event, getTouchAngle());
}
else {
if (!distance) {
if ( event.target.get('tag')!='a' &&
!event.target.getParent('.cerabox-close') &&
!event.target.getParent('.cerabox-left') &&
!event.target.getParent('.cerabox-right')
) {
cerabox.fireEvent('click', event);
event.stop();
if (cerabox.getElement('.cerabox-close').getStyle('opacity')!=1) {
showHud();
}
else {
hideHud();
}
}
}
touchCancel();
}
}
else {
touchCancel();
}
}
function touchCancel() {
startPos = {x:null, y:null};
endPos = {x:null, y:null};
}
function getTouchDistance() {
return Math.round(Math.sqrt(Math.pow(endPos.x - startPos.x,2) + Math.pow(endPos.y - startPos.y,2)));
}
function getTouchAngle() {
var x = startPos.x - endPos.x;
var y = endPos.y - startPos.y;
var angle = Math.round(Math.atan2(y,x)*180/Math.PI);
if (angle < 0)
angle = 360 - Math.abs(angle);
return angle;
}
function fireTouchEvent(event, angle) {
if (angle>=315 || angle<=45) {
cerabox.getElement('.cerabox-right').fireEvent('click', event);
}
else if (angle>=135 && angle<=225) {
cerabox.getElement('.cerabox-left').fireEvent('click', event);
}
touchCancel();
}
function preventScrolling(on) {
if (on) {
document.addEvent('mousewheel', stopScrollingEvent);
document.addEvent('keydown', stopScrollingEvent);
} else {
document.removeEvent('mousewheel', stopScrollingEvent);
document.removeEvent('keydown', stopScrollingEvent);
}
}
function stopScrollingEvent(event) {
event.preventDefault();
}
return _instance;
})(window);
// Single element
Element.implement({
cerabox: function(options){
return this.store('cerabox', new CeraBox(this, options));
}
});
// Collection
Elements.implement({
cerabox: function(options){
if (!options || typeOf(options.group)=='null' || options.group===true) {
var box = new CeraBox(this, options);
this.each(function(item){
item.store('cerabox', box);
});
}
else {
this.each(function(item){
item.store('cerabox', new CeraBox(item, options));
});
}
return this;
}
});
Element.implement({
setFocus: function(index) {
this.setAttribute('tabIndex',index || 0);
this.focus();
}
});
})(window);