/* Handling the communication between php processing server and local ajax engine */ /* Databap class */ function Databap() { self = this; //on load init this.init = function() { //Global constants self.consts.default_hash = self.vars.page_to_hash[self.consts.default_page]; self.consts.process_url = 'index.php'; self.consts.app_image_folder = 'images/'; self.consts.add_code_text = 'Copier le code ici.'; self.consts.search_box_text = 'Recherche...'; self.consts.maxHeight = $(window).innerHeight(); self.consts.maxWidth = $(window).innerWidth(); self.consts.time = (new Date()).getTime(); self.consts.transTime = 200; //Global variables self.vars2('tmp', 'object'); self.vars2('loading', 'boolean'); self.vars2('fade', false); self.vars2('page_cache', 'object'); self.vars2('pageIcon', 'string'); self.vars2('current_page', 'string'); self.vars2('current_user', 'object'); self.vars2('code', 'integer'); self.vars2('id', 0); self.vars2('phrase', 'string'); self.vars2('code_container', 'string'); self.vars2('focus', true); self.vars2('disconnected', 'boolean'); self.vars2('mode', 'string'); self.vars2('search_words', 'string'); self.vars2('initLoaded', 'boolean'); self.vars2('chans_list', 'object'); //shortcuts self.$main = $('#main'); self.$menu = $('#menu'); self.$title = $('#page_title'); self.consts.pageMaxHeight = self.$main.height(); self.consts.pageMaxWidth = self.$main.width(); //Global Events Listeners self.initSearch(); //Left menu self.initMenu(); //Events handler self.resetEventHandlers(); $(document).keyup(function(e){self.onKeyUp(e);}); $(document).keydown(function(e){self.onKeyDown(e);}); $(document).mouseenter(function(){self.onMouveEnter();}); $(document).mouseleave(function(){self.onMouveLeave();}); $(window).unload(function(){self.onQuit();}); //window.onbeforeunload = self.onQuit; $(window).resize(self.resizeMain).resize(); $(window).bind('hashchange', self.onHashChange); //Init first page if(self.hash()=='logout') self.goToInternalLink(self.vars.page_to_hash['welcome']); else if(self.hash()=='') self.goToInternalLink(self.consts.default_hash, self.consts.default_id); //Fix for old links else self.onHashChange(); //Load cache self.loadCache(); }; this.parseHash = function() { var sHash = self.hash(); var asHash = sHash.split('-'); var sPage = self.vars.hash_to_page[asHash[0]]; var iItemId = (typeof asHash[1] != 'undefined')?asHash[1]:0; //var iItemId = (typeof asHash[1] != 'undefined' && !isNaN(asHash[1]))?asHash[1]:0; //var sItemName = (typeof asHash[1] != 'undefined' && isNaN(asHash[1]))?asHash[1]:''; return {hash:sHash, page:sPage, id:iItemId/*, name:sItemName*/}; }; this.onHashChange = function(aoOptions) { aoOptions = aoOptions || {noFade:false, force:false}; var bNoFade = aoOptions.noFade || false; var bForce = aoOptions.force || false; var sDefaultPage = self.vars.current_page==''?'welcome':'error'; var asUrlVars = self.parseHash(); self.switchPage((asUrlVars.hash!='' && typeof asUrlVars.page !== 'undefined')?asUrlVars.page:sDefaultPage, asUrlVars.id, bNoFade, bForce); }; this.hash = function(hash) { if(!hash) return window.location.hash.slice(1); else { window.location.hash = (hash.substr(0, 1)=='#'?'':'#')+hash; //favicon, bug firefox var link = $('link[rel="shortcut icon"]').remove().attr("href"); $('').appendTo('head'); } }; //TODO Add images, ... this.loadCache = function() { var iDelay = 1; for(var i in self.vars.page_to_hash) { setTimeout('self.addPageToCache("'+i+'", function(){});', iDelay*60*1000); iDelay += 1; } }; this.vars2 = 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.vars2(asVarName, oValue); }; this.resetEventHandlers = function() { //Reset specific pages event catchers self.onResize = function(){}; self.resetSize = function(){}; self.onKeyUp = function(e){}; self.onKeyDown = function(e){}; self.onMouveEnter = function(){}; self.onMouveLeave = function(){}; self.onQuit = function(){return true;}; }; this.initSearch = function() { $('#form_header').submit(function(event){event.preventDefault();}); var bDirectSearch = (self.vars.current_page=='' && self.parseHash().page=='search' && self.parseHash().id!=''); $('#query') .addDefaultValue(self.consts.search_box_text, bDirectSearch?self.parseHash().id:'') .keyup(function(e){if(e.which==13 || e.isTrigger) self.goToInternalLink('search', $('#query').val());}); $('#search_btn_submit').click(function(){$('#query').trigger('keyup');}); }; this.initMenu = function() { //Hover Event: open/close self.$menu.hover ( self.openMenu, function() { closeMenu = true; if(typeof oMenuTimer != "undefined") clearTimeout(oMenuTimer); oMenuTimer = setTimeout(self.closeMenu, 1000); } ); //Close on click self.$menu.find('a').click(self.instantCloseMenu); }; this.openMenu = function() { //Disable closing closeMenu = false; if(typeof oMenuTimer != "undefined") clearTimeout(oMenuTimer); //If not already opened / about to open if(typeof openedMenu == 'undefined' || openedMenu != true) { openedMenu = true; self.$menu.find('#menu_title').hide(); //Main shadow self.$main.add(self.$title) .click(self.instantCloseMenu) .fadeTo('fast', 0.2); //Switch useless button self.$menu.find('.useless_button').removeClass('round').addClass('tiny_top_right'); //Move menu items var iVPos = Math.max(0, $(window).scrollTop() - 46 - 46); self.$menu.find('#menu_items').css('margin-top', iVPos); //Expand menu self.$menu .stop() .animate ( {width:'300px'/*, borderWidth:'10px'*/}, 'fast', function() { self.$menu.find('#menu_box').show(); $(this).addClass('opened'); } ); } }; this.instantCloseMenu = function() { closeMenu=true; if(typeof oMenuTimer != "undefined") clearTimeout(oMenuTimer); self.closeMenu(); }; this.closeMenu = function() { if(closeMenu == true) { if(typeof oMenuTimer != "undefined") clearTimeout(oMenuTimer); //Switch uselecc button self.$menu.find('.useless_button').removeClass('tiny_top_right').addClass('round'); //Main shadow self.$main.add(self.$title) .off('click') .fadeTo('fast', 1); //Reduce menu self.$menu.find('#menu_box').hide(); self.$menu .stop() .animate ( {width:'20px'/*, borderWidth:'0'*/}, 'fast', function() { self.$menu.find('#menu_title').show(); $(this).removeClass('opened'); } ); openedMenu = false; closeMenu = false; } }; this.setInitEnd = function(bEnded, bAddScrollBar) { self.vars.initLoaded = bEnded; if(self.vars.initLoaded===true) { //self.resizeMain(); self.onResize(); //setTimeout(self.onResize, 500); } }; this.getMainElem = function(elem) { return self.$main.find(elem); }; //switch to a new page with animation, without processing image this.switchPage = function(sNextPage, iItemId, bNoFade, bforce) { iItemId = iItemId || 0; bforce = bforce || false; //FIXME event object instead of string after cancelling page exit. bug ? channeling from parseHash if(bforce || typeof sNextPage == 'string' && (sNextPage != self.vars.current_page || iItemId!=self.vars.id)) { //Officially quiting page var bExit = true; if(self.vars.current_page!='') bExit = self.onQuit(); if(bExit==false) bExit = confirm('Voulez-vous vraiment quitter la page en cours ?'); if(bExit) { //Init's Start self.setInitEnd(false); //Reset specific pages event catchers self.resetEventHandlers(); //Switching data self.vars.current_page = sNextPage; self.vars.id = iItemId; /*if(typeof self.vars.page_cache[sNextPage] == 'undefined') { self.vars.loading = true; $.get ( self.getPagePath(sNextPage), function(data) { self.vars.loading = false; self.vars.page_cache[sNextPage] = data; self.transition(self.switchContent); } ); } else self.transition(self.switchContent); */ self.addPageToCache(sNextPage, function(){self.transition(self.switchContent);}); } //fix the hash else self.goToInternalLink(self.vars.current_page, self.vars.id); } }; this.addPageToCache = function(sPage, fOnSuccess) { if(typeof self.vars.page_cache[sPage] == 'undefined') { self.vars.loading = true; $.get ( self.getPagePath(sPage), function(data) { self.vars.loading = false; self.vars.page_cache[sPage] = data; fOnSuccess(); } ); } else fOnSuccess(); }; this.transition = function(fOnFinish) { if(self.vars2('fade')) $.when(self.$main.add(self.$title).stop().fadeTo(self.consts.transTime, 0)).done(fOnFinish); else fOnFinish(); self.vars2('fade', false); }; this.switchContent = function() { //Add page Header self.$title .find('.side_margins').attr('id', self.vars.current_page+'_title') .find('#title_text').text(self.vars.page_titles[self.vars.current_page]); self.$title.fadeTo(self.consts.transTime, 1); self.vars.pageIcon = 'fa-c-'+self.vars.current_page; self.pageIcon(self.vars.pageIcon); //Page replacement self.$main.empty().fadeTo(self.consts.transTime, 1).append(self.vars.page_cache[self.vars.current_page]); //Browser tab title self.setTitle(); //Reset specific page variables self.vars2('tmp', {}); //Page specific Actions self.pageInit(); }; this.pageIcon = function(pageIcon, comment) { self.$title .find('h1').attr('title', comment || '') .find('#page_icon') .attr('class', 'fa fa-fw fa-20') .addClass(pageIcon); }; this.addBufferIcon = function() { self.pageIcon('fa-spin fa-c-loading', 'Processing...'); }; this.addSuccessIcon = function() { self.pageIcon('fa-c-ok', 'Opération réussie'); setTimeout(self.resetIcon, 2000); }; this.addFailIcon = function(sMsg) { if(!sMsg) sMsg = 'Echec de connexion. Essaie de refresh la page'; self.pageIcon('fa-c-ko', sMsg); setTimeout(self.resetIcon, 5000); }; this.resetIcon = function() { self.pageIcon(self.vars.pageIcon, ''); }; this.resizeMain = function() { //Maximize main div height to fill up the page var iPageHeight = $('body').outerHeight(true); var iWindowHeight = $(window).innerHeight(); self.$main.height('+='+(iWindowHeight - iPageHeight)); self.$menu.height($('#main_container').height()); //Update size self.consts.maxHeight = $(window).innerHeight(); self.consts.maxWidth = $(window).innerWidth(); self.consts.pageMaxHeight = self.$main.innerHeight(); self.consts.pageMaxWidth = self.$main.innerWidth(); //Page event self.onResize(); self.updateScrollBar(); }; this.maximizeElem = function($Elem, bfitToElemContent, $Box) { $Box = $Box || self.$main; bfitToElemContent = bfitToElemContent || false; //Maximize to box height var iDelta = $Box.getEmptyHeight(); //debug('Giving empty '+iDelta+'px (in #'+$Box.attr('id')+') to #'+$Elem.attr('id')+' (originally : '+$Elem.height()+')'); if(iDelta != 0) $Elem.height('+='+iDelta); //debug('Now, #'+$Elem.attr('id')+' height is '+$Elem.height()+'px'); //Minimize to elem height if(bfitToElemContent) { iDelta = $Elem.getEmptyHeight(); if(iDelta > 0) $Elem.height('-='+iDelta); //debug('Removing useless '+iDelta+'px from #'+$Elem.attr('id')); } }; this.saveForm = function(action, $form, fOnSuccess, bProcessIcon, dataType, asVars) { var sFormVars = $form.serialize()+($.isEmptyObject(asVars)?'':'&'+$.param(asVars)); bProcessIcon = bProcessIcon || false; if(bProcessIcon) self.addBufferIcon(); if(!dataType) dataType = 'text'; self.vars.loading = true; $.ajax( { type: 'POST', url: self.getActionLink(action), data: sFormVars, dataType: dataType }) .done(function(result) { self.vars.loading = false; self.vars.disconnected = false; if(bProcessIcon) self.resetIcon(); fOnSuccess(result); }) .fail(function(jqXHR, textStatus, errorThrown) { self.vars.loading = false; self.vars.disconnected = true; debug('Error databap.js 331'); self.showError(textStatus); }); }; this.getInfo = function(action, fOnSuccess, vars, type, fOnError, bProcessIcon) { if(!vars) vars = {}; if(!type) type = 'html'; bProcessIcon = bProcessIcon || false; if(bProcessIcon) self.addBufferIcon(); vars['a'] = action; self.vars.loading = true; $.ajax( { url: self.consts.process_url, data: vars, dataType: type }) .done(function(result) { if(result==self.consts.errors.disconnected) databap.refresh(); else if((result==self.consts.error || typeof result.success != 'undefined' && result.success==self.consts.error) && typeof fOnError !== 'undefined') fOnError(); else { self.vars.loading = false; self.vars.disconnected = false; if(bProcessIcon) self.resetIcon(); fOnSuccess(result); } }) .fail(function(jqXHR, textStatus, errorThrown) { if(jqXHR.responseText==self.consts.errors.disconnected) databap.refresh(); self.vars.loading = false; self.vars.disconnected = true; debug('Error databap.js 361'); if(bProcessIcon) self.resetIcon(); if(!fOnError) { self.showError(textStatus); debug(textStatus+' '+errorThrown); } else fOnError(textStatus); }); }; this.getSyncInfo = function(action, vars) { if(!vars) vars = {}; vars['a'] = action; return $.ajax ( { url: self.consts.process_url, type: "GET", data: vars, dataType: "html", async: false, success: function(r){/*debug('getSyncInfo: Ok');*/} } ).responseText; }; this.showError = function(textStatus) { //debug('ERROR : '+textStatus); self.addFailIcon(); }; this.getUserInfo = function(fOnSuccess) { if(typeof self.vars.current_user.name == 'undefined') { self.getInfo ( 'user_info', function(user) { self.vars.current_user = user; fOnSuccess(user); }, {}, 'json' ); } else fOnSuccess(self.vars.current_user); }; this.appendItem = function(asItemInfo, $Container, $bAnimation) { //Filling up the item line var $verHtml = $(self.consts.versionHtml); $verHtml.find('#description').html(asItemInfo.title); $verHtml.find('#author_name').html(asItemInfo.name); $verHtml.find('#author_company').html(asItemInfo.company); $verHtml.find('#led').html(asItemInfo.led); //Rank (search) if(typeof asItemInfo.rank != 'undefined') { $verHtml.find('.glue-right') .append( $('', {'class':'rank'}) .append($('', {'class':'fa fa-inline fa-c-kpi'})) .append(asItemInfo.rank) ); } //Icon $verHtml.find('#type_logo').addClass('fa-c-'+asItemInfo.type); //Link var sItemLink = self.getInternalLink(asItemInfo.type, asItemInfo.id_item); $verHtml.find('#item_link').attr('href', sItemLink).attr('title', 'Lien vers '+sItemLink); $verHtml = self.setElemTags($verHtml, asItemInfo.id_item, false, asItemInfo.type); //Display $bAnimation = (typeof $bAnimation != 'undefined')?$bAnimation:true; var $Container = self.getMainElem('#list_container'); if($bAnimation) $verHtml.hide().appendTo($Container).slideDown('fast'); else $verHtml.appendTo($Container); }; this.getActionLink = function(sAction, oVars) { if(!oVars) oVars = {}; sVars = ''; for(i in oVars) { sVars += '&'+i+'='+oVars[i]; } return self.consts.process_url+'?a='+sAction+sVars; }; this.getInternalLink = function(sPage, iItemId, bAbsolute) { bAbsolute = bAbsolute || false; if(sPage.length==1) sPage = self.vars.hash_to_page[sPage]; //if hash is provided instead of page return (bAbsolute?self.vars.serv_name:'')+'#'+sPage+((iItemId>0 || iItemId!='')?'-'+escape($.trim(iItemId)):''); }; this.goToInternalLink = function(sPage, iItemId, bFade) { self.vars2('fade', bFade || false); iItemId = iItemId || 0; var sHash = self.getInternalLink(sPage, iItemId).substr(1); if(sHash==self.hash()) self.onHashChange({force:true}); else self.hash(sHash); }; this.refresh = function() { self.tmp("refresh", true); //self.goToInternalLink(databap.vars.current_page, databap.vars.id); location.reload(true); }; this.goToExternalLink = function(sUrl) { window.location = sUrl; }; this.appendCode = function(codeBox, info) { self.vars.id = info.id_code; self.vars.phrase = (!info.phrase)?info.id_code:info.phrase; //#code_reader $codeBox = self.setElemTags($(codeBox), [self.vars.id]); //About code self.getMainElem('#'+self.getElemTag('code_lines', self.vars.id)).html(info.code); self.getMainElem('#'+self.getElemTag('description', self.vars.id)).html(info.description); //About author self.getMainElem('#'+self.getElemTag('author_name', self.vars.id)).text(info.name); self.getMainElem('#'+self.getElemTag('author_company', self.vars.id)).text(info.company); self.getMainElem('#'+self.getElemTag('led', self.vars.id)).text(info.led); self.getMainElem('#'+self.getElemTag('item_link', self.vars.id)) .prop('href', self.getInternalLink('code', info.id_code)) .find('.fa').addClass('fa-c-code'); }; this.setElemTags = function($CodeBox, aiIds, bUpdate, sType) { self.setElemTag($CodeBox, aiIds, bUpdate, sType); $CodeBox.find('[id]').each(function(){self.setElemTag($(this), aiIds, bUpdate, sType);}); return $CodeBox; }; this.setElemTag = function($Tag, aiIds, bUpdate, sType) { var sCurTagId = $Tag.attr('id'); //Replace only ids existing in aiIds, keep the others if(bUpdate) { var aiCurTagIds = self.getElemIds(sCurTagId); for(i in aiIds) { aiCurTagIds[i] = aiIds[i]; } aiIds = aiCurTagIds; } var sNewTagId = self.getElemTag(self.stripElemIds(sCurTagId), aiIds, sType); $Tag.attr('id', sNewTagId); if($Tag.attr('name') != undefined) $Tag.attr('name', sNewTagId); }; this.getElemTag = function(sTag, aiIds, sType) { if(!sType) sType = 'c'; if(typeof aiIds != 'object') aiIds = [aiIds]; return sType+implode(self.consts.id_sep, aiIds)+self.consts.id_sep+sTag; }; this.getFirstElemId = function(sTag) { var aiIds = self.getElemIds(sTag); return aiIds[0]; }; this.getElemIds = function(sTag) { return array_filter(explode(self.consts.id_sep, sTag.substr(1)), isNumeric); }; this.stripElemIds = function(sTag) { //var sPattern = 'c\\d+'+self.consts.id_sep; var sType = sTag.substr(0, 1); var sPattern = self.getElemTag('', '\\d+', sType); if(self.checkRegExMatch(sPattern, sTag)) { sTag = sTag.substr(self.getElemTag('', self.getElemIds(sTag), sType).length); } return sTag; }; this.checkRegExMatch = function(sPattern, sText) { var oRegEx = new RegExp(sPattern, 'i'); return sText.match(oRegEx); }; this.setCodeContainer = function(fOnSuccess, containerId) { if(typeof self.vars.code_container === 'undefined' || self.vars.code_container == '') { self.getInfo ( 'code_block', function(code_block) { self.vars.code_container = code_block; if(containerId) self.appendContainer(containerId); fOnSuccess(); } ); } else { if(containerId) self.appendContainer(containerId); fOnSuccess(); } }; this.appendContainer = function(containerId, codeId) { if(containerId != '') { if(!codeId) { codeBoxId = 'code_reader'; container = self.vars.code_container; } else { codeBoxId = self.getElemTag('code_reader', codeId); container = self.vars.code_container.replace('id="code_reader"', 'id="'+codeBoxId+'"'); } self.getMainElem(containerId).append(container); return codeBoxId; } else { return false; } }; this.getImagePath = function(imageName) { return 'url("'+self.consts.app_image_folder+imageName+'")'; }; this.getPagePath = function(sPageName) { return self.consts.mask_folder+sPageName+'.html?'+self.consts.time; }; this.addPunctuation = function(sMsg) { var asPunctuations = ['?', '!', '.', ',', ':', ';', '-', '/']; return sMsg+($.inArray(sMsg.slice(-1), asPunctuations)==-1?'.':''); }; this.addErrorBefore = function(msg, elem) { self.addMsgBefore(this.addPunctuation(msg), 'error', elem); }; this.addWarningBefore = function(msg, elem) { msg = 'Attention : '+this.addPunctuation(msg); self.addMsgBefore(msg, 'warning', elem); }; this.addSuccessBefore = function(msg, elem) { self.addMsgBefore(this.addPunctuation(msg), 'success', elem); }; this.addMsgBefore = function(msg, msgClass, elem) { var $msg = $('

', {'class':msgClass}).append($('', {'class':'fa fa-inline fa-c-'+msgClass})).append(msg); $msg.hide().insertBefore(elem).slideDown('fast', function(){databap.updateScrollBar('bottom');}).delay(5000).slideUp('fast', function(){$(this).remove();databap.updateScrollBar();}); }; this.feedback = function(sClass, sMsg) { $('', {'class':'feedback '+sClass}) .append($('', {'class':'fa fa-inline fa-c-'+sClass})) .append(self.addPunctuation(sMsg)) .appendTo('#title_feedback') .slideDown('fast') .delay(5000) .slideUp('fast', function(){$(this).remove();}); }; this.setTitle = function(extra) { extra = extra || ''; if(extra!='') extra += ' | '; var page = self.vars.page_titles[self.vars.current_page]; if(self.vars.id) page += ' '+self.vars.id; document.title = extra+'Databap '+chr('8226')+' '+page; }; this.initScrollBar = function(sBox, sSubBox, sContent) { self.tmp('scrollbar', {}); //TODO in page switch $(sSubBox) .before('

') .addClass('scrollbar_box round'); $(sContent).addClass('scrollbar_subbox'); self.tmp('scrollbar', $(sBox).tinyscrollbar({viewport:sSubBox, overview:sContent})); }; this.setScrollBarSize = function(iBoxSize) { if(self.tmp('scrollbar')) { var $Box = self.tmp('scrollbar').find('.scrollbar_box'); if(iBoxSize=='optimize') self.maximizeElem($Box, true); else if(iBoxSize=='maximize') self.maximizeElem($Box, false); else $Box.height(iBoxSize); self.updateScrollBar(); } }; this.updateScrollBar = function(sPos) { sPos = sPos || 'relative'; if(self.tmp('scrollbar')) self.tmp('scrollbar').tinyscrollbar_update(sPos); }; this.isScrollBarAtBottom = function() { return self.tmp('scrollbar').tinyscrollbar_isBottom(); }; this.unifyWidth = function($ItemsSet) { var iMaxWidth = 0; $ItemsSet.each(function(){iMaxWidth = Math.max(iMaxWidth, $(this).width());}); $ItemsSet.each(function(){if($(this).width() < iMaxWidth) $(this).width(iMaxWidth);}); }; this.shareEvent = function(sType, iId) { if(iId!='') { $('#share') .hide() .text(self.getInternalLink(sType, iId, true)) .addClass('addr') .slideDown('fast') .unbind('click'); } }; }