Files
spot/script/spot.js

368 lines
9.9 KiB
JavaScript
Executable File

function Spot(asGlobals)
{
self = this;
this.consts = asGlobals.consts;
this.consts.hash_sep = '-';
this.consts.title = 'Spotty';
this.consts.default_page = 'project';
this.consts.timezone = Intl.DateTimeFormat().resolvedOptions().timeZone || this.consts.default_timezone;
/* Initialization */
this.init = function()
{
//Variables & constants from php
self.vars('tmp', 'object');
self.vars('page', 'string');
self.updateVars(asGlobals.vars);
//page elem
self.elem = {};
self.elem.container = $('#container');
self.elem.main = $('#main');
self.resetTmpFunctions();
//On Key down
$('html').on('keydown', function(oEvent){self.onKeydown(oEvent);});
//on window resize
$(window).on('resize', function(){self.onResize();});
//Setup menu
//self.initMenu();
//Hash management
$(window)
.bind('hashchange', self.onHashChange)
.trigger('hashchange');
};
this.updateVars = function(asVars)
{
$.each(asVars, function(sKey, oValue){self.vars(sKey, oValue)});
};
/* Variable Management */
this.vars = function(oVarName, oValue)
{
var asVarName = (typeof oVarName == 'object')?oVarName:[oVarName];
//Set, name & type / default value (init)
if(typeof oValue !== 'undefined') setElem(self.vars, copyArray(asVarName), oValue);
//Get, only name parameter
return getElem(self.vars, asVarName);
};
this.tmp = function(sVarName, oValue)
{
var asVarName = (typeof sVarName == 'object')?sVarName:[sVarName];
asVarName.unshift('tmp');
return self.vars(asVarName, oValue);
};
/* Interface with server */
this.get = function(sAction, fOnSuccess, oVars, fOnError, fonProgress)
{
if(!oVars) oVars = {};
fOnError = fOnError || function(sError) {console.log(sError);};
fonProgress = fonProgress || function(sState){};
fonProgress('start');
oVars['a'] = sAction;
oVars['t'] = self.consts.timezone;
return $.ajax(
{
url: self.consts.process_page,
data: oVars,
dataType: 'json'
})
.done(function(oData)
{
fonProgress('done');
if(oData.desc.substr(0, self.consts.lang_prefix.length)==self.consts.lang_prefix) oData.desc = self.lang(oData.desc.substr(5));
if(oData.result==self.consts.error) fOnError(oData.desc);
else fOnSuccess(oData.data, oData.desc);
})
.fail(function(jqXHR, textStatus, errorThrown)
{
fonProgress('fail');
fOnError(textStatus+' '+errorThrown);
});
};
this.lang = function(sKey, asParams) {
var sParamType = $.type(asParams);
if(sParamType == 'undefined') asParams = [];
else if($.type(asParams) != 'array') asParams = [asParams];
var sLang = '';
if(sKey in self.consts.lang) {
sLang = self.consts.lang[sKey];
for(i in asParams) sLang = sLang.replace('$'+i, asParams[i]);
}
else console.log('missing translation: '+sKey);
return sLang;
};
/* Page Switch - Trigger & Event catching */
this.onHashChange = function()
{
var asHash = self.getHash();
if(asHash.hash !='' && asHash.page != '') self.switchPage(asHash); //page switching
else if(self.vars('page')=='') self.setHash(self.consts.default_page); //first page
};
this.getHash = function()
{
var sHash = self.hash();
var asHash = sHash.split(self.consts.hash_sep);
var sPage = asHash.shift() || '';
return {hash:sHash, page:sPage, items:asHash};
};
this.setHash = function(sPage, asItems, bReboot)
{
bReboot = bReboot || false;
sPage = sPage || '';
asItems = asItems || [];
if(typeof asItems == 'string') asItems = [asItems];
if(sPage != '')
{
var sItems = (asItems.length > 0)?self.consts.hash_sep+asItems.join(self.consts.hash_sep):'';
self.hash(sPage+sItems, bReboot);
}
};
this.hash = function(hash, bReboot)
{
bReboot = bReboot || false;
if(!hash) return window.location.hash.slice(1);
else window.location.hash = '#'+hash;
if(bReboot) location.reload();
};
/* Page Switch - DOM Replacement */
this.getActionLink = function(sAction, oVars)
{
if(!oVars) oVars = {};
sVars = '';
for(i in oVars)
{
sVars += '&'+i+'='+oVars[i];
}
return self.consts.process_page+'?a='+sAction+sVars;
};
this.resetTmpFunctions = function()
{
self.pageInit = function(asHash){console.log('no init for the page: '+asHash.page)};
self.onSamePageMove = function(asHash){return false};
self.onQuitPage = function(){return true};
self.onResize = function(){};
self.onFeedback = function(sType, sMsg){};
self.onKeydown = function(oEvent){};
};
this.switchPage = function(asHash)
{
var sPageName = asHash.page;
var bSamePage = self.vars('page')==sPageName;
if(self.onQuitPage(bSamePage) && !bSamePage || self.onSamePageMove(asHash))
{
//Delete tmp variables
self.vars('tmp', {});
//disable tmp functions
self.resetTmpFunctions();
//Officially a new page
var bFirstPage = self.vars('page')=='';
self.vars('page', sPageName);
//Update Page Title
this.setPageTitle(sPageName+' '+(asHash.items[0] || ''));
//Replacing DOM
var $Dom = $(self.consts.pages[sPageName]);
if(bFirstPage)
{
self.splash($Dom, asHash, bFirstPage); //first page
}
else
{
self.elem.main.stop().fadeTo('fast', 0, function(){self.splash($Dom, asHash, bFirstPage);}); //Switching page
}
}
};
this.setPageTitle = function(sTitle) {
document.title = self.consts.title+' - '+sTitle;
};
this.splash = function($Dom, asHash, bFirstPage)
{
//Switch main content
self.elem.main.empty().html($Dom);
//Page Bootstrap
self.pageInit(asHash, bFirstPage);
//Show main
var $FadeInElem = bFirstPage?self.elem.container:self.elem.main;
$FadeInElem.hide().fadeTo('slow', 1);
};
}
/* Common Functions */
function copyArray(asArray)
{
return asArray.slice(0); //trick to copy array
}
function getElem(aoAnchor, asPath)
{
return (typeof asPath == 'object' && asPath.length > 1)?getElem(aoAnchor[asPath.shift()], asPath):aoAnchor[(typeof asPath == 'object')?asPath.shift():asPath];
}
function setElem(aoAnchor, asPath, oValue)
{
var asTypes = {boolean:false, string:'', integer:0, int:0, array:[], object:{}};
if(typeof asPath == 'object' && asPath.length > 1)
{
var nextlevel = asPath.shift();
if(!(nextlevel in aoAnchor)) aoAnchor[nextlevel] = {}; //Creating a new level
if(typeof aoAnchor[nextlevel] !== 'object') debug('Error - setElem() : Already existing path at level "'+nextlevel+'". Cancelling setElem() action');
return setElem(aoAnchor[nextlevel], asPath, oValue);
}
else
{
var sKey = (typeof asPath == 'object')?asPath.shift():asPath;
return aoAnchor[sKey] = (!(sKey in aoAnchor) && (oValue in asTypes))?asTypes[oValue]:oValue;
}
}
function getTimeZoneDesc(sTimeZoneName) {
var sCity = sTimeZoneName.split('/')[1].replace('_', ' ') || '';
return oSpot.lang('city_time', sCity);
}
$.prototype.addInput = function(sType, sName, sValue, aoEvents)
{
aoEvents = aoEvents || [];
var $Input = $('<input>', {type: sType, name: sName, value: sValue}).data('old_value', sValue);
$.each(aoEvents, function(iIndex, aoEvent) {
$Input.on(aoEvent.on, aoEvent.callback);
});
return $(this).append($Input);
};
$.prototype.addButton = function(sIcon, sText, sName, fOnClick, sClass)
{
sText = sText || '';
sClass = sClass || '';
var $Btn = $('<button>', {name: sName, 'class':sClass})
.addIcon('fa-'+sIcon, (sText != ''))
.append(sText)
.click(fOnClick);
return $(this).append($Btn);
};
$.prototype.addIcon = function(sIcon, bMargin, sStyle)
{
bMargin = bMargin || false;
sStyle = sStyle || '';
return $(this).prepend($('<i>', {'class':'fa'+sStyle+' '+sIcon+(bMargin?' push':'')}));
};
$.prototype.defaultVal = function(sDefaultValue)
{
$(this)
.data('default_value', sDefaultValue)
.val(sDefaultValue)
.addClass('defaultText')
.focus(function()
{
var $This = $(this);
if($This.val() == $This.data('default_value')) $This.val('').removeClass('defaultText');
})
.blur(function()
{
var $This = $(this);
if($This.val() == '') $This.val($This.data('default_value')).addClass('defaultText');
});
};
$.prototype.checkForm = function(sSelector)
{
sSelector = sSelector || 'input[type="text"], textarea';
var $This = $(this);
var bOk = true;
$This.find(sSelector).each(function()
{
$This = $(this);
bOk = bOk && $This.val()!='' && $This.val()!=$This.data('default_value');
});
return bOk;
};
$.prototype.cascadingDown = function(sDuration)
{
return $(this).slideDown(sDuration, function(){$(this).next().cascadingDown(sDuration);});
};
$.prototype.hoverSwap = function(sDefault, sHover)
{
return $(this)
.data('default', sDefault)
.data('hover', sHover)
.hover(function(){
var $This = $(this),
sHover = $This.data('hover');
sDefault = $This.data('default');
if(sDefault!='' && sHover != '') {
$This.fadeOut('fast', function() {
var $This = $(this);
$This.text((sDefault==$This.text())?sHover:sDefault).fadeIn('fast');
});
}
})
.text(sDefault);
};
$.prototype.onSwipe = function(fCallBack){
return $(this)
.on('mousedown touchstart', function(e) {
var $This = $(this);
$This.data('x-down', e.pageX);
$This.data('y-down', e.pageY);
})
.on('mouseup touchend',function (e) {
var $This = $(this);
var iDeltaX = e.pageX - $This.data('x-down');
var iDeltaY = e.pageY - $This.data('y-down');
fCallBack({x:iDeltaX, y:iDeltaY});
});
};
function isIE() {
var sUA = window.navigator.userAgent;
//IE 10: Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; Trident/6.0)
//IE 11: Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko
//Edge 12 (Spartan): Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36 Edge/12.0
//Edge 13: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2486.0 Safari/537.36 Edge/13.10586
//Edge 18: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36 Edge/18.18363
return (sUA.indexOf('MSIE ') > 0 || sUA.indexOf('Trident/') > 0 || sUA.indexOf('Edge/') > 0);
}