1/** @namespace Init */ 2/*! 3 * Este archivo lleva las acciones que se han de ejecutar 4 * cuando esta cargado el dom y cuando está cargada la página. 5 * 6 * Copyright(c) Divisa Informática y Telecomunicaciones S.A. 7 */ 8 9if(typeof(_rootWeb) != 'string' && window.top && typeof(window.top._rootWeb) == 'string') { 10 var _rootWeb = window.top._rootWeb; 11} 12if(typeof(_userLocale) != 'string' && window.top && typeof(window.top._userLocale) == 'string') { 13 var _userLocale = window.top._userLocale; 14} 15if(typeof(_userLocaleLang) != 'string' && window.top && typeof(window.top._userLocaleLang) == 'string') { 16 var _userLocaleLang = window.top._userLocaleLang; 17} 18if(typeof(_userLocaleCountry) != 'string' && window.top && typeof(window.top._userLocaleCountry) == 'string') { 19 var _userLocaleCountry = window.top._userLocaleCountry; 20} 21 22/** 23 * Devuelve la versión actual de Proxia 24 * @returns {string} Proxia versión 25 * @memberOf Init 26 */ 27function getProxiaVersion() { 28 var metaGenerator = $("meta[name=generator]"); 29 if(metaGenerator.length > 0) 30 return metaGenerator.attr("content"); 31 else 32 return "Proxia© Content Manager"; 33} 34 35/** 36 * Configuración por defecto de las tooltip para todo el portal 37 * @type {{position: {corner: {target: string, tooltip: string}}, style: {name: string}, show: {effect: {type: qTipDefaults.show.effect.type}}, hide: {fixed: boolean, effect: {type: qTipDefaults.hide.effect.type}}}} 38 * @memberOf Init 39 */ 40qTipDefaults = { 41 position: { 42 corner: { 43 target: 'center', 44 tooltip: 'topLeft' 45 } 46 }, 47 style: { 48 name: 'light' 49 }, 50 // sobrescribimos los efectos al mostrar y ocultar, para evitar que en ie 51 // nos aparezca el bug con el cleartype de las fuentes al aplicar filtros 52 show: { 53 effect: { 54 type: function(){ (!$.browser.msie) ? $(this).fadeIn() : $(this).show(); } 55 } 56 }, 57 hide: { 58 fixed: true, 59 effect: { 60 type: function(){ (!$.browser.msie) ? $(this).fadeOut() : $(this).hide(); } 61 } 62 } 63} 64 65/** 66 * Función que devuelve el dominio completo de una url 67 * @param {string} str - Url a comprobar 68 * @returns {string} - Dominio 69 * @memberOf Init 70 */ 71function getDomain(str) { 72 if(str && str != "") { 73 _domain = str.match(/:\/\/(.[^/]+)/); 74 if(_domain != null && _domain.length > 0) { 75 return _domain[1]; 76 } 77 } 78 return ""; 79} 80 81/** 82 * Función que devuelve la parte de dominio de una url 83 * @param {string} url Url a comprobar 84 * @returns {string} Dominio 85 * @memberOf Init 86 */ 87function getDomainName(url) { 88 var url_parts = url.split('/'); 89 var domain_name_parts = url_parts[2].split(':'); 90 var domain_name = domain_name_parts[0]; 91 var domain_parts = domain_name.split('.'); 92 // Si existen subdominios sólo cogemos la parte del dominio 93 if(domain_parts.length >= 2){ 94 domain_name = domain_parts[domain_parts.length-2]; 95 domain_name += "."+domain_parts[domain_parts.length-1]; 96 } 97 return domain_name; 98} 99 100/** 101 * Función que devuelve la clave del flowPlayer en función del dominio 102 * @returns {string} Clave del flowPlayer 103 * @memberOf Init 104 */ 105function getFlpKey() { 106 var domain_name = getDomainName(window.location.href); 107 for(var i= 0; i < flpKeys.length; i++) { 108 if(flpDomains[i].toLowerCase() == domain_name.toLowerCase()) { 109 return flpKeys[i]; 110 } 111 } 112 // Devolvemos una key por defecto si no hemos encontrado una 113 return flpKeys[0]; 114} 115 116/** 117 * Array para flowPlayer con los respectivos dominios y keys 118 * @type {Array} 119 * @memberOf Init 120 */ 121var flpDomains = "{flowplayer.domains}".split(","); 122 123/** 124 * Array para flowPlayer con los respectivos dominios y keys 125 * @type {Array} 126 * @memberOf Init 127 */ 128var flpKeys = "#daef8215901bf76af63".split(","); 129 130var flpSettings = ''; 131 132/** 133 * Función que carga los settings para el Flowplayer 134 * @memberOf Init 135 */ 136function loadflpSettings(){ 137 // Settings que utilizamos para embeber el Flowplayer dentro del prettyPhoto 138 if(flpSettings!='') return; 139 140 // Si el idioma no está soportado cargamos en inglés 141 var supportedLanguages = ['en','es','fr','pt','nl','de']; 142 var scriptToLoad = _rootWeb+'/javaScript/flowplayer/lang/flowplayer-en.js'; 143 if($.inArray(_userLocaleLang, supportedLanguages) != -1) { 144 scriptToLoad = _rootWeb+'/javaScript/flowplayer/lang/flowplayer-'+_userLocaleLang+'.js'; 145 } 146 147 loadScript({ url: scriptToLoad, success: function(){ 148 flpSettings = '"key": "'+getFlpKey()+'",'+ 149 '"logo": {'+ 150 ' "url": "'+_rootWeb+'/imagenes/video/logo.png",'+ 151 ' "bottom": 22,'+ 152 ' "right": 22,'+ 153 ' "width": 40,'+ 154 ' "height": 40,'+ 155 ' "opacity": 0.8,'+ 156 ' "fullscreenOnly": false,'+ 157 ' "displayTime": 10,'+ 158 ' "fadeSpeed": 300'+ 159 '},'+ 160 '"plugins": {'+ 161 ' "controls": {'+ 162 ' "autoHide": "always",'+ 163 ' "stop": true,'+ 164 ' "tooltips": {'+ 165 ' "buttons": true, '+ 166 ' "play" : "'+ FlowPlayer.TT['PLAY'] +'", '+ 167 ' "pause" : "'+FlowPlayer.TT['PAUSE']+'", '+ 168 ' "mute" : "'+FlowPlayer.TT['MUTE']+'", '+ 169 ' "unmute" : "'+FlowPlayer.TT['UNMUTE']+'", '+ 170 ' "stop" : "'+ FlowPlayer.TT['STOP']+'", '+ 171 ' "fullscreen" : "'+FlowPlayer.TT['FULLSCREEN']+'", '+ 172 ' "fullscreenExit" : "'+FlowPlayer.TT['FULLSCREEN_EXIT']+'", '+ 173 ' "next" : "'+FlowPlayer.TT['NEXT']+'", '+ 174 ' "previous" : "'+FlowPlayer.TT['PREVIOUS']+'"'+ 175 ' }'+ 176 ' }'+ 177 '}, '+ 178 '"clip": {'+ 179 ' "url": "{path}",'+ 180 ' "scaling": "orig",'+ 181 ' "accelerated": false,'+ 182 ' "linkWindow": "_blank"'+ 183 '},'+ 184 '"contextMenu": ['+ 185 ' "'+getProxiaVersion()+'",'+ 186 ' "Powered by Flowplayer"'+ 187 ']'; 188 }}); 189} 190 191/**
192 * Función que carga el prettyPhoto 193 * @memberOf Init 194 */ 195function loadPrettyPhoto() { 196 $("a[rel^='prettyPhoto']:not(.cmPhotoSwipe),a[data-rel^='prettyPhoto']:not(.cmPhotoSwipe)").prettyPhoto({ 197 flowplayerSettings: flpSettings 198 }); 199} 200 201/** 202 * Función que carga el FlowPlayer 203 * @memberOf Init 204 */ 205function loadFlowPlayer() { 206 var $videos = $('a.cmAutoVideo,a.cmAutoVideoNoAlt'); 207 if($videos.length > 0) { 208 209 // Activamos el flowplayer, en primer lugar nos aseguramos de que el funcionamiento 210 // es el correcto limpiando y eliminado aquellos elementos que no funcionan, el 211 // A debe estar vacÃo para que empiece el auto-play del video y el href no puede 212 // tener caracteres &, puesto que esto afecta al parseado JSON del flowplayer. 213 $('em.cmAutoVideoNoAlt,a.cmAutoVideoNoAlt').show(); // Aquellos videos que no tienen imagen de splash 214 215 // Cogemos el nombre del recurso y lo añadimos antes del enlace 216 $videos.each(function() { 217 $(this).wrap("<em class=\"cmEmbeddedResource\"/>"); 218 var _em = $(this).parent(); 219 _em.prepend($("span", $(this))); 220 221 // Añadimos al EM las clases css del enlace 222 var classes = ($(this).attr("class")).split(' '); 223 for(var i = 0; i < classes.length; i++) { 224 var currentClass = $.trim(classes[i]); 225 if(currentClass.indexOf('cmEmbedImage') != -1) $(this).removeClass(currentClass); 226 _em.addClass(currentClass); 227 } 228 229 // Eliminamos el contenido del enlace antes de insertar el object del flowplayer 230 $(this).empty(); 231 }); 232 233 // Vamos a modificar la URL del href..., si tehemos un atributo 234 // path quiere decir que tenemos que utilizar este en lugar 235 // de extractar el idMmedia que es la opción que estamos aplicando 236 // hasta ahora. 237 $('a.cmAutoVideo').attr('href',function() { 238 // Recuperamos el Ãndice base. 239 var currentUrl = this.href 240 var _baseIndex = currentUrl.indexOf('tkShowResource'); 241 // Comportamiento antiguo. 242 if(_baseIndex != -1) { 243 var hasPath = currentUrl.indexOf('path'); 244 if(hasPath!=-1) { 245 // Ahora tenemos que encontrar el siguiente & o en su defecto el fin 246 var _nextAmp = currentUrl.indexOf('&',hasPath); 247 var url = false; 248 if(_nextAmp!=-1) { 249 url = currentUrl.substring(hasPath+5,_nextAmp); 250 } else { 251 url = currentUrl.substring(hasPath+5); 252 } 253 return url; 254 } else { 255 // Ahora, tenemos que obtener los datos 256 var _idMmediaIndx = currentUrl.indexOf('idMmedia='); 257 // Ahora tenemos que encontrar el siguiente & o en su defecto el fin 258 var _nextAmp = currentUrl.indexOf('&',_idMmediaIndx); 259 260 var _url = currentUrl.substring(0,_baseIndex)+'images?idMmedia='; 261 if(_nextAmp != -1) { 262 _url+=currentUrl.substring(_idMmediaIndx+9,_nextAmp); 263 } else { 264 _url+=currentUrl.substring(_idMmediaIndx+9); 265 } 266 return _url; 267 } 268 } else { 269 // En el comportamiento nuevo el nombre del recurso sera 270 // del tipo path_base/s,id-fichero, tenemos que eliminar 271 // el caracter s, 272 var tmpImage = currentUrl; 273 var baseImage = ''; 274 if(tmpImage.indexOf('/')!=-1) { 275 baseImage = tmpImage.substring(0,tmpImage.lastIndexOf('/')+1); 276 tmpImage = tmpImage.substring(tmpImage.lastIndexOf('/')+1); 277 } 278 if(tmpImage.indexOf('g,') == 0 || tmpImage.indexOf('s,') == 0 || 279 tmpImage.indexOf('f,') == 0) { 280 tmpImage = tmpImage.substring(2); 281 } 282 return baseImage+tmpImage; 283 } 284 }); 285 286 // Instanciamos los flowplayer. 287 flowplayer("a.cmAutoVideo", _rootWeb+"/javaScript/flowplayer/flowplayer.unlimited-3.1.5.swf",{ 288 key: getFlpKey(), 289 logo: { 290 url: _rootWeb+'/imagenes/video/logo.png', 291 bottom: 22, 292 right: 22, 293 width: 40, 294 height: 40, 295 opacity: 0.8, 296 fullscreenOnly: false, 297 displayTime: 10, 298 fadeSpeed: 300 299 }, 300 plugins: { 301 controls: { 302 tooltipColor: '#70c6a9', 303 tooltipTextColor: '#000000', 304 sliderColor: '#70c6a9', 305 volumeSliderColor: '#70c6a9', 306 autoHide: 'always', 307 stop: true, 308 tooltips: { 309 buttons: true, 310 play: FlowPlayer.TT['PLAY'], 311 pause: FlowPlayer.TT['PAUSE'], 312 mute: FlowPlayer.TT['MUTE'], 313 unmute: FlowPlayer.TT['UNMUTE'], 314 stop: FlowPlayer.TT['STOP'], 315 fullscreen: FlowPlayer.TT['FULLSCREEN'], 316 fullscreenExit: FlowPlayer.TT['FULLSCREEN_EXIT'], 317 next: FlowPlayer.TT['NEXT'], 318 previous: FlowPlayer.TT['PREVIOUS'] 319 } 320 } 321 }, 322 clip: { 323 scaling: 'orig', 324 accelerated: false, 325 linkWindow: '_blank' 326 }, 327 contextMenu: [ 328 // Indicamos que es un video Powered by Proxia 329 getProxiaVersion(), 330 "Powered by Flowplayer" 331 ] 332 }); 333 334 // En el caso de que el video no tenga imagen de inicio, decimos 335 // que la reproducción no se inicie de forma automática... 336 $('a.cmAutoVideoNoAlt').flowplayer().each(function() { 337 this.onLoad(function() { 338 this.getClip(0).update({autoPlay:false}); 339 }); 340 }); 341 342 // Añadimos al EM las mismas dimensiones que las de su enlace hijo 343 $('em.cmAutoVideoNoAlt').each(function() { 344 $(this).css('width',$("a", $(this)).css('width')); 345 $(this).css('height',$("a", $(this)).css('height')); 346 }); 347 }; 348 349 // Plugin para el modelo videoteca 350 if($("#videoteca,#videotecaPlayer").length > 0) { 351 352 // Número de videos a mostrar en el scrolling, 353 // si no hemos especificado uno previamente... 354 if(typeof(videotecaSize) != 'number') videotecaSize = 4; 355
356 // Proporcionamos scrolling a la barra horizontal de videos 357 $("#videoteca").scrollable({items:'div.entries', size:videotecaSize, clickable:false}); 358 359 // Configuración del flowplayer 360 flowplayer("videotecaPlayer", _rootWeb+"/javaScript/flowplayer/flowplayer.unlimited-3.1.5.swf", { 361 key: getFlpKey(), 362 logo: { 363 url: _rootWeb+'/imagenes/video/logo.png', 364 bottom: 22, 365 right: 22, 366 width: 40, 367 height: 40, 368 opacity: 0.8, 369 fullscreenOnly: false, 370 displayTime: 10, 371 fadeSpeed: 300 372 }, 373 plugins: { 374 controls: { 375 autoHide: 'always', 376 stop: true, 377 tooltips: { 378 buttons: true, 379 play: FlowPlayer.TT['PLAY'], 380 pause: FlowPlayer.TT['PAUSE'], 381 mute: FlowPlayer.TT['MUTE'], 382 unmute: FlowPlayer.TT['UNMUTE'], 383 stop: FlowPlayer.TT['STOP'], 384 fullscreen: FlowPlayer.TT['FULLSCREEN'], 385 fullscreenExit: FlowPlayer.TT['FULLSCREEN_EXIT'], 386 next: FlowPlayer.TT['NEXT'], 387 previous: FlowPlayer.TT['PREVIOUS'] 388 } 389 } 390 }, 391 clip: { 392 scaling: 'orig', 393 accelerated: false, 394 linkWindow: '_blank', 395 baseUrl: _rootWeb + '/cm/' 396 }, 397 contextMenu: [ 398 // Indicamos que es un video Powered by Proxia 399 getProxiaVersion(), 400 "Powered by Flowplayer" 401 ] 402 }).playlist("div.entries"); 403 } 404} 405 406/*! 407 * Este archivo implementa ciertas funcionalidades de carga de scripts y CSS 408 * 409 * Copyright(c) Divisa Informática y Telecomunicaciones S.A. 410 */ 411 412// Array donde guardamos los ficheros (css/js) ya cargados 413var loadedFiles = []; 414 415/** 416 * Función que carga un css de forma dinámica 417 * @param {string} cssFile - Ruta al fichero a enlazar 418 * @memberOf Init 419 */ 420function loadCSS(cssFile){ 421 422 // Añadimos el parámetro nc a la URL 423 var _url = appendNoCache(cssFile); 424 425 var _src = prepareLoadedFile(_url); 426 427 // Si ya lo hemos cargado no lo volvemos a cargar 428 if(loadedFiles[_src]) return; 429 430 var cssLink=document.createElement("link"); 431 cssLink.setAttribute("rel", "stylesheet"); 432 cssLink.setAttribute("type", "text/css"); 433 cssLink.setAttribute("href", _url); 434 document.getElementsByTagName("head")[0].appendChild(cssLink); 435 436 // Almacenamos en un array el fichero que acabamos de cargar 437 loadedFiles[_src] = true; 438 loadedFiles[_src+'.success'] = true; 439} 440 441/** 442 * Carga un conjunto de ficheros de forma asÃncrona en el sistema, sin esperar a que se 443 * cargue uno para cargar el siguiente. 444 * 445 * @param scriptArray El array de scripts a cargar 446 */ 447function loadSetOfScripts(scriptArray) { 448 for(var i=0;i<scriptArray.length;i++) { 449 loadScript({url:scriptArray[i]}); 450 } 451} 452 453/** 454 * Función de callback asociado a la carga de un fichero para permitir recursividad 455 * @param {array} urlArray - Array con todas las urls que tenemos que cargar 456 * @param {number} index - La posición del Ãndice en la que estamos evaluando 457 * @param successFunction - Callback cuando todo ha ido bien. 458 * @memberOf Init 459 */ 460function loadScriptFile(urlArray, index, 461 successFunction) { 462 var i = index+1; 463 if(urlArray.length > i) { 464 loadScript({url: urlArray[i], success: function() { 465 // Nos llamamos de forma recursiva. 466 loadScriptFile(urlArray,i,successFunction); 467 }}); 468 469 } else { 470 if(typeof successFunction == 'function') { 471 successFunction(); 472 } 473 } 474} 475 476/** 477 * Carga un javaScript de forma dinámica 478 * @param {Object} opts - Las opciones 479 * @param {string} opts.url - Url del JS 480 * @param {boolean} opts.success - El estado 481 * @param {boolean} opts.error - Si hay error 482 * @memberOf Init 483 */ 484function loadScript(opts){ 485 if(opts.url == false || opts.url == 'undefined' || opts.url == null) { 486 opts.success(); 487 } 488 489 // Permitimos un paso de un array de scripts que deben cargarse de forma 490 // secuencial y cuando terminen cargamos el que tenemos asociado. 491 if(opts.url instanceof Array) { 492 var i = 0; 493 loadScript({url: opts.url[0], success:function() { 494 loadScriptFile(opts.url,0,opts.success); 495 }}); 496 return; 497 } 498 499 // Añadimos el parámetro nc a la URL 500 var _url = appendNoCache(opts.url); 501 502 // Si ya lo hemos cargado no lo volvemos a cargar 503 var _src = prepareLoadedFile(_url); 504 505 if(loadedFiles[_src]) { 506 // En cualquier caso ejecutamos la función callback si existe 507 if(opts.success) { 508 if(loadedFiles[_src+'.success']) { 509 opts.success(); 510 } else { 511 // Si otro proceso inició la carga pero aún no ha acabado, 512 // tendremos que esperar para ejecutar el callback 513 var scriptInterval = setInterval(function() { 514 if(loadedFiles[_src+'.success']) { 515 clearInterval(scriptInterval); 516 opts.success(); 517 } 518 if(loadedFiles[_src+'.error']) { 519 clearInterval(scriptInterval); 520 } 521 }, 100); 522 } 523 } 524 return; 525 } 526 527 var script = document.createElement('script'); 528 script.setAttribute('type', 'text/javascript'); 529 script.setAttribute('src', _url); 530 if(opts.error) script.onerror = opts.error; 531 document.getElementsByTagName("head")[0].appendChild(script); 532 533 // Almacenamos en un array el fichero para que no se vuelva a cargar otra vez 534 var _src = prepareLoadedFile(_url); 535 loadedFiles[_src] = true; 536 537 script.onload = script.onreadystatechange = function(){ 538 if ( !this.readyState || this.readyState == "loaded" || this.readyState == "complete" ) { 539 if(opts.success) opts.success(); 540 541 // Registramos la finalización con éxito de la carga del fichero 542 loadedFiles[_src+'.success'] = true; 543 544 // Handle memory leak in IE 545 script.onload = script.onreadystatechange = null; 546 } else { 547 // Registramos la finalización con error de la carga del fichero 548 loadedFiles[_src+'.error'] = true; 549 } 550 }; 551}; 552 553/**
554 * Función que añade a una url el parametro noCache 555 * @param {string} _url - Url 556 * @returns {string} La url a devolver 557 * @memberOf Init 558 */ 559function appendNoCache(_url) { 560 if(typeof(_noCache) == 'string' && _url.indexOf('nc=') == -1) { 561 if(_url.indexOf('?') != -1) { 562 _url += '&'; 563 } else { 564 _url += '?'; 565 } 566 _url += _noCache; 567 } 568 return _url; 569} 570 571/** 572 * Función que prepara el archivo para cargarlo 573 * @param {string} _src - Source 574 * @returns {string} Source 575 * @memberOf Init 576 */ 577function prepareLoadedFile(_src) { 578 if(_src.indexOf("//") != -1) _src = _src.substr(_src.indexOf("//") + 2); 579 if(_src.indexOf("?") != -1) _src = _src.substr(0, _src.indexOf("?")); 580 if(_src.indexOf("/") != -1) _src = _src.substr(_src.indexOf("/")); 581 582 return _src; 583} 584 585/** 586 * Función que inicializa el plugin prettyPhoto para imágenes, videos,... 587 * @param fnOnLoad 588 * @memberOf Init 589 */ 590function initPrettyPhoto(fnOnLoad) { 591 // Si el idioma no está soportado cargamos en inglés 592 var supportedLanguages = ['en','es','fr','pt','nl','de']; 593 var scriptToLoad = _rootWeb+'/javaScript/prettyPhoto/js/lang/prettyPhoto-en.js'; 594 if($.inArray(_userLocaleLang, supportedLanguages) != -1) { 595 scriptToLoad = _rootWeb+'/javaScript/prettyPhoto/js/lang/prettyPhoto-'+_userLocaleLang+'.js'; 596 } 597 loadCSS(_rootWeb+'/javaScript/prettyPhoto/css/prettyPhoto.css'); 598 loadflpSettings(); 599 if(typeof ($.fn.prettyPhoto) == "undefined") { 600 loadScript({ url: scriptToLoad, success: function(){ 601 loadScript({ url: _rootWeb+'/javaScript/prettyPhoto/js/jquery.prettyPhoto.js', success: function(){ 602 loadPrettyPhoto(); 603 if(typeof fnOnLoad == 'function') fnOnLoad(); 604 }}); 605 }}); 606 }else{ 607 loadPrettyPhoto(); 608 if(typeof fnOnLoad == 'function') fnOnLoad(); 609 } 610} 611 612/** 613 * Función que inicializa el plugin flowPlayer para videos... 614 * @memberOf Init 615 */ 616function initFlowPlayer() { 617 loadflpSettings(); 618 if(typeof ($.fn.flowplayer) == "undefined") { 619 loadScript({ url: _rootWeb+'/javaScript/flowplayer/flowplayer-3.1.4.min.js', success: function(){ 620 loadScript({ url: _rootWeb+'/javaScript/flowplayer/flowplayer.playlist-3.0.7.min.js', success: function(){ 621 loadFlowPlayer(); 622 }}); 623 }}); 624 }else{ 625 loadFlowPlayer(); 626 } 627} 628 629/** 630 * Función que carga el plugin photoSwipe para recursos multimedia 631 * @param {string} $container - El lugar en el que se va a cargar el plugin 632 * @param {string} callback - El callback 633 * @memberOf Init 634 */ 635function initPhotoSwipe($container, callback) { 636 637 loadflpSettings(); 638 if(typeof(PhotoSwipe) != 'function') { 639 loadCSS(_rootWeb+'/javaScript/photoswipe/photoswipe.css'); 640 loadCSS(_rootWeb+'/javaScript/photoswipe/default-skin/default-skin.css'); 641 loadScript({ url: _rootWeb+'/javaScript/photoswipe/photoswipe.min.js', success: function(){ 642 loadScript({ url: _rootWeb+'/javaScript/photoswipe/photoswipe-ui-default.min.js', success: function(){ 643 loadPhotoSwipe($container); 644 if(typeof(callback) == 'function') callback($container); 645 }}); 646 }}); 647 } else { 648 loadPhotoSwipe($container); 649 if(typeof(callback) == 'function') callback($container); 650 } 651 652} 653 654/** 655 * Función que inicializa el plugin photoSwipe para recursos multimedia 656 * @param {string} $container=body - El lugar en el que se va a inicializar el plugin 657 * @memberOf Init 658 */ 659function loadPhotoSwipe($container) { 660 661 if(!$container) $container = $("body"); 662 663 var markupPhotoSwipe = ' \ 664 <div class="pswp" tabindex="0" role="dialog" aria-hidden="true"> \ 665 <div class="pswp__bg"></div> \ 666 <div class="pswp__scroll-wrap"> \ 667 <div class="pswp__container"> \ 668 <div class="pswp__item"></div> \ 669 <div class="pswp__item"></div> \ 670 <div class="pswp__item"></div> \ 671 </div> \ 672 <div class="pswp__ui pswp__ui--hidden"> \ 673 <div class="pswp__top-bar"> \ 674 <div class="pswp__counter"></div> \ 675 <div class="pswp__buttons"> \ 676 <button class="pswp__button pswp__button--zoom" title="'+photoSwipeText.zoomInOut+'"></button> \ 677 <button class="pswp__button pswp__button--fs" title="'+photoSwipeText.toggleFullscreen+'"></button> \ 678 <button class="pswp__button pswp__button--share" title="'+photoSwipeText.sharePhoto+'"></button> \ 679 <button class="pswp__button pswp__button--close" title="'+photoSwipeText.closePhoto+'"></button> \ 680 </div> \ 681 <div class="pswp__preloader"> \ 682 <div class="pswp__preloader__icn"> \ 683 <div class="pswp__preloader__cut"> \ 684 <div class="pswp__preloader__donut"></div> \ 685 </div> \ 686 </div> \ 687 </div> \ 688 </div> \ 689 <div class="pswp__share-modal pswp__share-modal--hidden pswp__single-tap"> \ 690 <div class="pswp__share-tooltip"></div> \ 691 </div> \ 692 <button class="pswp__button pswp__button--arrow--left" title="'+photoSwipeText.prevPhoto+'"> </button> \ 693 <button class="pswp__button pswp__button--arrow--right" title="'+photoSwipeText.nextPhoto+'"> </button> \ 694 <div class="pswp__caption" tabindex="0"> \ 695 <div class="pswp__caption__center"> \ 696 <div class="pswp__caption__title"></div> \ 697 <div class="pswp__caption__description"></div> \ 698 <div class="pswp__caption__author"></div> \ 699 </div> \ 700 </div> \ 701 </div> \ 702 </div> \ 703 </div> \ 704 '; 705 706 if($("body >
706 div.pswp").length == 0) { 707 var $markupPhotoSwipe = $(markupPhotoSwipe); 708 $("body").append($markupPhotoSwipe); 709 710 // para que el foco pueda ser circular dentro del modal 711 $('div.pswp__caption', $markupPhotoSwipe).off("focusin").on("focusin", function(e) { 712 e.preventDefault(); 713 $markupPhotoSwipe.focus(); 714 }); 715 } 716 717 var photoSwipeOptions = { 718 history: false, 719 errorMsg: '<div class="pswp__error-msg">' + photoSwipeText.loadErrMsg + '</div>', 720 selector: 'a.cmPhotoSwipe,area.cmPhotoSwipe', 721 showAnimationDuration : 333, 722 hideAnimationDuration : 333, 723 closeOnScroll: false, 724 shareButtons: [ 725 {id:'facebook', label:photoSwipeText.shareOnFacebook, url:'https://www.facebook.com/sharer/sharer.php?u={{image_url}}'}, 726 {id:'twitter', label:photoSwipeText.shareOnTwitter, url:'https://twitter.com/intent/tweet?text={{text}}&url={{image_url}}'}, 727 {id:'pinterest', label:photoSwipeText.shareOnPinterest, url:'https://www.pinterest.com/pin/create/button/?url={{url}}&media={{image_url}}&description={{text}}'}, 728 {id:'download', label:photoSwipeText.downloadMedia, url:'{{raw_image_url}}', download:true} 729 ] 730 }; 731 732 // GalerÃas de imágenes 733 var $photoSwipeGalleries = $("div.cmImageGallery, ul.cm-img-gallery-list", $container); 734 if($photoSwipeGalleries.length > 0) { 735 $photoSwipeGalleries.each(function() { 736 if($("a.cmPhotoSwipe", $(this)).first().data("init")) return true; 737 photoSwipe(photoSwipeOptions, this); 738 $("a.cmPhotoSwipe", $(this)).data("init", true); 739 }); 740 } 741 742 // Imágenes individuales 743 var $photoSwipeImages = $container.hasClass("cmPhotoSwipe") ? $container : $("a.cmPhotoSwipe", $container); 744 $photoSwipeImages.each(function() { 745 if($(this).first().data("init")) return true; 746 photoSwipe(photoSwipeOptions, this); 747 $(this).data("init", true); 748 }); 749} 750 751/** 752 * Función que abre un enlace de tipo imagen con photoSwipe 753 * @param {object} obj - Objeto en el que se abre el enlace 754 * @param {string} type=image - El tipo 755 * @returns {boolean} 756 * @memberOf Init 757 */ 758function openPhotoSwipe(obj, type) { 759 if(!type) type = 'image'; 760 var $obj = $(obj); 761 762 if($obj.hasClass("cmPhotoSwipe")) return false; 763 764 $obj.addClass("cmPhotoSwipe"); 765 $obj.attr("data-type", type); 766 $obj.attr("data-title", $obj.attr("title") || $obj.attr("alt") || $obj.attr("data-original-title")); 767 $obj.removeAttr("onclick").off("click"); 768 769 var href = $obj.attr("href"); 770 href = href.replace('/g,','/').replace('/s,','/').replace('/f,','/'); 771 772 $obj.attr("data-href", href); 773 774 if(type == 'image') { 775 $("<img/>").load(function(){ 776 var w = $(this).width(); 777 var h = $(this).height(); 778 $(this).remove(); 779 if(w && h) $obj.attr("data-size", w.toString()+"x"+h.toString()); 780 781 initPhotoSwipe($obj, function($this) { 782 $this.trigger("click"); 783 }); 784 785 }).attr("src", href).hide().appendTo("body"); 786 } else { 787 initPhotoSwipe($obj, function($this) { 788 $this.trigger("click"); 789 }); 790 } 791 792 return false; 793} 794 795/** 796 * Función que monta una galerÃa 797 * @param {object} options - Opciones de configuracion 798 * @param selector 799 * @memberOf Init 800 */ 801function photoSwipe(options, selector){ 802 var galleries = [], 803 _options = options; 804 805 var markups = { 806 flash: ' \ 807 <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"> \ 808 <param name="wmode" value="transparent" /> \ 809 <param name="allowfullscreen" value="true" /> \ 810 <param name="allowscriptaccess" value="always" /> \ 811 <param name="movie" value="{href}" /> \ 812 <embed src="{href}" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" wmode="transparent"></embed> \ 813 </object> \ 814 ', 815 audio: ' \ 816 <i class="fa fa-file-audio-o"></i> \ 817 <audio controls="controls" preload="auto" autoplay="autoplay" src="{href}"> \ 818 Your browser does not support the audio element. \ 819 </audio> \ 820 ', 821 video: ' \ 822 <video controls="controls" preload="auto" autoplay="autoplay" src="{href}"> \ 823 Your browser does not support the video element. \ 824 </video> \ 825 ', 826 flv: ' \ 827 <object id="fp_pphoto" type="application/x-shockwave-flash" data="'+_rootWeb+'/javaScript/flowplayer/flowplayer.unlimited-3.1.5.swf"> \ 828 <param name="movie" value="'+_rootWeb+'/javaScript/flowplayer/flowplayer.unlimited-3.1.5.swf"/> \ 829 <param name="wmode" value="transparent" /><param name="allowfullscreen" value="true"/> \ 830 <param name="flashvars" value=\'config={{flpSettings}}\'/> \ 831 </object> \ 832 ', 833 ebook: ' \ 834 <object id="ebook" type="application/x-shockwave-flash" data="'+_rootWeb+'/javaScript/pageflip/pageflip_loader.swf"> \ 835 <param name="movie" value="'+_rootWeb+'/javaScript/pageflip/pageflip_loader.swf"/> \ 836 <param name="wmode" value="transparent" /> \ 837 <param name="allowfullscreen" value="true"/> \ 838 <param name="allowscriptaccess" value="samedomain"/> \ 839 <param name="menu" value="true"/> \ 840 <param name="bgcolor" value="#4B4B4B"/> \ 841 <param name="flashvars" value="XMLfn={href}"/> \ 842 <param name="base" value="'+_rootWeb+'/javaScript/pageflip/"/> \ 843 </object> \ 844 ', 845 jpageflip: ' \ 846 <div id="jpfBody"> \ 847 <div class="jpfLoader"></div> \ 848 <div class="jpfContainer"> \ 849 <div class="jpfTopContainer"> \ 850 <div class="jpfHead"></div> \ 851 <div class="jpfNav"> \ 852 <a class="jpfFirst jpfNavButton" href="javascript:;" rel="toolTip"><img src="'+_rootWeb+'/javaScript/jpageflip/images/first.png" alt=""/></a> \ 853 <a class="jpfPrev jpfNavButton" href="javascript:;" rel="toolTip"><img src="'+_rootWeb+'/javaScript/jpageflip/images/prev.png" alt=""/></a> \ 854 <div class="jpfNavFormPagesDiv"> \ 855 <form class="jpfNavFormPages" name="jpfNavFormPages" action=""> \ 856 <input class="jpfNavFormPagesInput" name="jpfNavFormPagesInput" type="text" value=""/> \ 857 </form> \ 858 </div> \ 859 <a class="jpfNext jpfNavButton" href="javascript:;" rel="toolTip"><img src="'+_rootWeb+'/javaScript/jpageflip/images/next.png" alt=""/></a> \ 860 <a class="jpfLast jpfNavButton" href="javascript:;" rel="toolTip"><img src="'+_rootWeb+'/javaScript/jpageflip/images/last.png" alt=""/></a> \ 861 </div> \ 862 </div> \ 863 <div class="jpfLeftContainer"> \ 864 <a class="jpfPrevBig" href="javascript:;"><img class="arrowNav" src="'+_rootWeb+'/javaScript/jpageflip/images/prevBig.png" width="40" alt="" /></a> \ 865 </div> \ 866 <div class="jpfRightContainer"> \ 867 <a class="jpfNextBig" href="javascript:;"><img class="arrowNav" src="'+_rootWeb+'/javaScript/jpageflip/images/nextBig.png" width="40" alt="" /></a> \ 868 </div> \ 869 <div class="jpfContainerInner"> \ 870 <div class="jpfTopContainerInner"></div> \ 871 <div class="jpfDivForMoveContainer"> \ 872 <div class="jpfDivForMove"></div> \ 873 </div> \ 874 <div class="jpfInner" data-jpageflip="jPageFlip[path="{href}"][width="{width}"][height="{height}"]"> \ 875 <img src="'+_rootWeb+'/javaScript/jpageflip/images/clearpixel.gif"
875class="jPageFlip jPageFlipZero" alt="" /> \ 876 </div> \ 877 <div class="jpfBottomContainerInner"></div> \ 878 </div> \ 879 <div class="jpfBottomContainer"> \ 880 <div class="jpfBottom"> \ 881 <div class="jpfNavFormGoToDiv"> \ 882 <form class="jpfNavFormGoTo" name="jpfNavFormGoTo" action=""> \ 883 <label><span class="jpfNavFormGoToLabel"></span><input class="jpfNavFormGoToInput" name="jpfNavFormGoToInput" type="text" value=""/></label> \ 884 <button type="submit" name="jpfNavFormGoToButton" class="jpfNavFormGoToButton"><img src="'+_rootWeb+'/javaScript/jpageflip/images/navButton.png" alt="" /><span class="jpfNavFormGoToButtonText"></span></button> \ 885 </form> \ 886 </div> \ 887 <div class="jpfControlButtons"> \ 888 <a class="jpfFullscreen jpfNavButton" href="tkJPageFlip" rel="toolTip"><img src="'+_rootWeb+'/javaScript/jpageflip/images/fullscreen.png" alt="" /></a> \ 889 <a class="jpfThumbnails jpfNavButton" href="javascript:;" rel="toolTip"><img src="'+_rootWeb+'/javaScript/jpageflip/images/thumbnails.png" alt="" /></a> \ 890 <span class="jpfZoomEscale">100%</span> \ 891 <span class="jpfSliderZoom"> \ 892 <span class="jpfSliderZoomTitle">ZOOM</span> \ 893 <a class="jpfZoomMinus" rel="toolTip"></a> \ 894 <span class="jpfDraggerZoom" style="left:19px;top:13px;"></span> \ 895 <a class="jpfZoomMas" rel="toolTip"></a> \ 896 </span> \ 897 <a class="jpfPrintleft jpfNavButton" href="javascript:;" rel="toolTip"><img src="'+_rootWeb+'/javaScript/jpageflip/images/printleft.png" alt="" /></a> \ 898 <a class="jpfPrintright jpfNavButton" href="javascript:;" rel="toolTip"><img src="'+_rootWeb+'/javaScript/jpageflip/images/printright.png" alt="" /></a> \ 899 <a class="jpfDownloadPdf jpfNavButton" href="javascript:;" rel="toolTip"><img src="'+_rootWeb+'/javaScript/jpageflip/images/downloadPdf.png" alt="" /></a> \ 900 <span class="jpfSliderAutoFlip"><span class="jpfDraggerAutoFlip" style="left:6px;top:17px;"></span></span> \ 901 <span class="jpfAutoFlip"> \ 902 <a class="jpfPlay jpfNavButton" href="javascript:;" rel="toolTip"><img src="'+_rootWeb+'/javaScript/jpageflip/images/play.png" alt="" /></a> \ 903 <a class="jpfPause jpfNavButton" href="javascript:;" rel="toolTip"><img src="'+_rootWeb+'/javaScript/jpageflip/images/pause.png" alt="" /></a> \ 904 </span> \ 905 </div> \ 906 </div> \ 907 <div class="jpfFoot">Powered by <a href="http://www.proxiasuite.com" target="_blank">Proxia</a> ©</div> \ 908 </div> \ 909 <div class="jpfIframeHolder"></div> \ 910 </div> \ 911 </div> \ 912 ', 913 iframe: ' \ 914 <iframe src="{href}"></iframe> \ 915 ' 916 }; 917 918 var init = function($this){ 919 galleries = []; 920 921 var initPhotoSwipeOnResource = function(size, link, galleryId, photoId ){ 922 link.data('gallery-id',galleryId); 923 link.data('photo-id', photoId); 924 925 var item = {}; 926 item.type = link.data('type'); 927 item.title = link.data('title'); 928 item.description = link.data('description') && item.title != link.data('description') ? link.data('description') : ''; 929 item.author = link.data('author') ? '<strong>' + photoSwipeText.psAuthor + '</strong> ' + link.data('author') : ''; 930 931 var href = link.attr("data-href") || link.attr("href"); 932 href = href.replace('/g,','/').replace('/s,','/').replace('/f,','/'); 933 934 if(href.indexOf('/tkImageGalleryComponent?') != -1) { 935 href = href.replace('/tkImageGalleryComponent?', '/images?'); 936 } 937 938 if(!item.type) return true; 939 940 item.type = item.type.toLowerCase(); 941 942 var flashSupport = typeof swfobject !== 'undefined' && swfobject.getFlashPlayerVersion().major !== 0; 943 944 var jPageFlipLoaded = false; 945 if(item.type == 'ebook' && !flashSupport) { 946 item.type = 'jpageflip'; 947 if(!jPageFlipLoaded) { 948 loadCSS(_rootWeb+'/javaScript/jpageflip/css/jPageFlip.css'); 949 loadScript({ url: _rootWeb+'/javaScript/jpageflip/js/jquery.jpageflip.js', success: function(){ 950 loadScript({ url: _rootWeb+'/javaScript/jquery.tipsy.js', success: function(){ 951 jPageFlipLoaded = true; 952 }}); 953 }}); 954 } 955 } 956 957 // slide with HTML 958 if(item.type == 'image') { 959 item.src = href; 960 item.msrc = link.children[0] ? link.children[0].getAttribute('src') : item.src; 961 item.w = parseInt(size[0],10); 962 item.h = parseInt(size[1],10); 963 item.el = link; 964 } else { 965 item.html = '<div class="pswp__content '+item.type+'" data-type="'+item.type+'" data-src="'+href+'"></div>'; 966 item.msrc = href; 967 } 968 969 galleries[galleryId - 1].items.push(item); 970 } 971 972 $this.each(function(i, gallery){ 973 galleries.push({ 974 id: i, 975 items: [] 976 }); 977 978 var $resources = $(selector).hasClass("cmPhotoSwipe") ? $(selector) : $(_options.selector, $(gallery)); 979 if($resources.length == 0) return; 980 981 $resources.each(function(k, link) { 982 var $link = $(link); 983 var isImage = $link.data('type')=='image'; 984 985 var size = $link.data('size') ? $link.data('size').split('x') : []; 986 987 if(size.length > 0 || !isImage) { 988 initPhotoSwipeOnResource(size,$link,i+1,k); 989 } else{ 990 var imagenUrl = $link.attr("href"); 991 var img = new Image(); 992 img.src = imagenUrl; 993 $(img).on('load',function() { 994 var w = img.width || 1920;
995 var h = img.height || 1080; 996 initPhotoSwipeOnResource([w,h],$link,i+1,k); 997 }); 998 } 999 }); 1000 1001 $resources.off('click').on('click', function(e){ 1002 e.preventDefault(); 1003 var gid = $(this).data('gallery-id'), 1004 pid = $(this).data('photo-id'); 1005 openGallery(gid,pid); 1006 }); 1007 }); 1008 } 1009 1010 var parseHash = function() { 1011 var hash = window.location.hash.substring(1), 1012 params = {}; 1013 1014 if(hash.length < 5) { 1015 return params; 1016 } 1017 1018 var vars = hash.split('&'); 1019 for (var i = 0; i < vars.length; i++) { 1020 if(!vars[i]) { 1021 continue; 1022 } 1023 var pair = vars[i].split('='); 1024 if(pair.length < 2) { 1025 continue; 1026 } 1027 params[pair[0]] = pair[1]; 1028 } 1029 1030 if(params.gid) { 1031 params.gid = parseInt(params.gid, 10); 1032 } 1033 1034 if(!params.hasOwnProperty('pid')) { 1035 return params; 1036 } 1037 params.pid = parseInt(params.pid, 10); 1038 return params; 1039 }; 1040 1041 var openGallery = function(gid,pid){ 1042 var pswpElement = document.querySelectorAll('.pswp')[0], 1043 items = galleries[gid-1].items, 1044 options = { 1045 index: pid, 1046 galleryUID: gid, 1047 getThumbBoundsFn: function(index) { 1048 var item = items[index]; 1049 if(!item || !item.el || !item.el.children[0]) return; 1050 var thumbnail = item.el.children[0], 1051 pageYScroll = window.pageYOffset || document.documentElement.scrollTop, 1052 rect = thumbnail.getBoundingClientRect(); 1053 1054 return {x:rect.left, y:rect.top + pageYScroll, w:rect.width}; 1055 }, 1056 addCaptionHTMLFn: function(item, captionEl) { 1057 var $caption = $(captionEl); 1058 var $title = $("div.pswp__caption__title", $caption); 1059 var $description = $("div.pswp__caption__description", $caption); 1060 var $author = $("div.pswp__caption__author", $caption); 1061 var hasCaption = false; 1062 if(item.title) { 1063 $title.html(item.title); 1064 hasCaption = true; 1065 } else { 1066 $title.empty(); 1067 } 1068 if(item.description) { 1069 $description.html(item.description); 1070 hasCaption = true; 1071 } else { 1072 $description.empty(); 1073 } 1074 if(item.author) { 1075 $author.html(item.author); 1076 hasCaption = true; 1077 } else { 1078 $author.empty(); 1079 } 1080 // Añadimos un class al contenedor con el tipo de recurso que estamos mostrando 1081 if(item.type) { 1082 $caption.closest("div.pswp").addClass("pswp__type_"+item.type); 1083 } 1084 return hasCaption; 1085 } 1086 }; 1087 $.extend(options,_options); 1088 var gallery = new PhotoSwipe( pswpElement, PhotoSwipeUI_Default, items, options); 1089 gallery.listen('afterChange', function() { 1090 var $container = $(this.container); 1091 var $current = $(this.currItem.container); 1092 if($current.length == 0) return; 1093 1094 onLightboxShown($("body > div.pswp")); 1095 1096 var $content = $("div.pswp__content", $current); 1097 $content.empty(); 1098 1099 var type = $content.data("type"); 1100 if(!type) return; 1101 1102 var markup = markups[type]; 1103 if(!markup) return; 1104 1105 var href = this.currItem.msrc || this.currItem.src; 1106 1107 markup = markup.replace(/{flpSettings}/g, flpSettings); 1108 markup = markup.replace(/{path}/g, '{href}'); 1109 markup = markup.replace(/{href}/g, href); 1110 markup = markup.replace(/{width}/g, $(window).outerWidth()); 1111 markup = markup.replace(/{height}/g, $(window).outerHeight()); 1112 1113 $content.html(markup); 1114 1115 if(type == 'jpageflip') { 1116 $.ajax({ 1117 type: 'post', 1118 url: href, 1119 success: function(xml) { 1120 var xmlResp = $("PageflipDataSet", xml); 1121 if($("PageData", xmlResp).attr('PageImage')){ 1122 $('div.jpfInner', $content).jPageFlip({ 1123 startPage : 1, 1124 defaultValueTipsy: {title: 'title', gravity: 's', html: true, cssClass: 'jpftipsy'} 1125 }); 1126 $('div.jpfContainer a[rel=toolTip]', $content).tipsy({title: 'title', gravity: 's', html: true, cssClass: 'jpftipsy'}); 1127 } 1128 } 1129 }); 1130 } 1131 }); 1132 gallery.listen('close', function() { 1133 var $container = $(this.container); 1134 var $current = $(this.currItem.container); 1135 var $content = $("div.pswp__content", $current); 1136 $content.empty(); 1137 onLightboxHidden($("body >
1137 div.pswp"), $(this.currItem.el)); 1138 }); 1139 1140 gallery.init(); 1141 } 1142 1143 // initialize 1144 init($(selector)); 1145 1146 // Parse URL and open gallery if it contains #&pid=3&gid=1 1147 var hashData = parseHash(); 1148 if(hashData.pid > 0 && hashData.gid > 0) { 1149 openGallery(hashData.gid,hashData.pid); 1150 } 1151} 1152 1153/** 1154 * Función que inicializa los calendarios 1155 * @memberOf Init 1156 */ 1157function initCalendarios() { 1158 // contenidos en modo calendario con tooltip 1159 var calendariosConTooltip = $("div.calendarWithTooltip"); 1160 if(calendariosConTooltip.length > 0){ 1161 calendariosConTooltip.each(function(){ 1162 var itemActual = $(this); 1163 $(this).addClass('activatedTooltip'); 1164 // hay que quitar el title de los enlaces ya que el hover se hace sobre los td 1165 $('.cmCalendarTable .calendarDayWithEvents .cmEventInCalendar .cmContentLink span', itemActual).removeAttr('title'); 1166 1167 // el tooltip de cada celda con eventos 1168 $('.cmCalendarTable .calendarDayWithEvents', itemActual).each(function(){ 1169 $(this).qtip({ 1170 // cogemos el contenido del tooltip 1171 content: { text: $($(this).find('.dayNumber a').attr('href')).html() }, 1172 position: qTipDefaults.position, 1173 style: qTipDefaults.style, 1174 show: qTipDefaults.show, 1175 hide: qTipDefaults.hide 1176 }); 1177 }); 1178 }); 1179 } 1180 1181 // contenidos en modo calendario con click que muestra / oculta el dia 1182 var calendariosConClick = $("div.calendarWithClick"); 1183 if(calendariosConClick.length > 0){ 1184 calendariosConClick.each(function(){ 1185 var itemActual = $(this); 1186 1187 // el evento click de cada celda con eventos 1188 $('.cmCalendarTable .calendarDayWithEvents', itemActual).click(function(){ 1189 // buscamos el id al que dirige el dia con evento 1190 var target = $(this).find('.dayNumber a').attr('href'); 1191 1192 // escondemos los posibles mensajes cuando no existen eventos en el dÃa actual o el mes actual 1193 $('.cmCalendarNoEvents', itemActual).hide(); 1194 1195 // primeramente escondemos el item visible 1196 $('div.cmMonthEventsContainer li.cmCalendarDay:visible', itemActual).hide(); 1197 $('div.cmMonthEventsContainer div.cmMonthContents').hide(); 1198 1199 // mostramos los eventos del dia clickado 1200 $(target).show(); 1201 1202 //buscamos si ha seleccionado un dia previamente 1203 var selectedDay = $('.selected-day', itemActual); 1204 if(selectedDay.length > 0){ 1205 //si ya habia un dia seleccionado le quitamos la clase 1206 selectedDay.removeClass('selected-day'); 1207 } 1208 1209 //añadimos class al dia seleccionado 1210 $(this).addClass('selected-day'); 1211 1212 return false; 1213 }); 1214 1215 // Si en la URL me viene informacion sobre un evento lo analizo 1216 var locationHref = location.href; 1217 var dateParamExist = false; 1218 if(locationHref.lastIndexOf('#') != -1) { 1219 var dayFromUrl = locationHref.substring(locationHref.lastIndexOf('#')); 1220 if(dayFromUrl.indexOf("_") != -1) { 1221 var urlDay = dayFromUrl.substring(dayFromUrl.indexOf("_")); 1222 var dayWithEvent = $(".cmCalendarTable .calendarDayWithEvents a[href$='"+urlDay+"']", itemActual); 1223 if(dayWithEvent.length > 0){ 1224 $('.cmCalendarNoEvents', itemActual).hide(); 1225 $(dayWithEvent.attr('href')).show(); 1226 dateParamExist = true; 1227 } 1228 } 1229 } 1230 1231 }); 1232 } 1233} 1234 1235/** 1236 * Función usada para cargar el calendario por ajax. 1237 * en el tag <cm:getChildrenList_2> se añade <dv2ee:setPluginProperty key="ajaxFunction" value="calendarAjax"/> 1238 * @param {string} url - La url a cargar 1239 * @param param - Los parametros 1240 * @param link - EL sitio en el que enlazar el calendario 1241 * @memberOf Init 1242 */ 1243function calendarAjax(url,param,link){ 1244 var linkContainer=$(link).closest("td.portalLayoutCell,div.portalLayoutCell,div.proxia-column").find("div:first"); 1245 1246 var calendarLoader=linkContainer.find('.calendarLoader'); 1247 if(calendarLoader.length > 0){ 1248 calendarLoader.css({'display':'block'}); 1249 }else{ 1250 linkContainer.prepend('<div class="calendarLoader"></div>'); 1251 } 1252 1253 linkContainer.find('.cmCalendarViewContainer').css({'opacity':'0.6'}); 1254 1255 if(url.indexOf('Ajax')==-1) url += 'Ajax'; 1256 $.ajax({ 1257 url: url, 1258 type: "POST", 1259 data: param, 1260 success: function(msg){ 1261 linkContainer.html(msg); 1262 initCalendarios(); 1263 } 1264 }); 1265} 1266 1267/** 1268 * This function decodes the data stored in data in the way ([key="value"])+, it converts this information to an array indexed by key 1269 * @param data - Data to decode 1270 * @returns {Array} Array decoded 1271 * @memberOf Init 1272 */ 1273function decodeMap(data) { 1274 // The regular expresion we are going to eval 1275 var regexExpr = /\[([^=]+)=\"([^\"]+)\"\]/g; 1276 var results = regexExpr.exec(data); 1277 // The array - in which we are going to store data (indexed as a map of arrays) 1278 var resultsArray = new Array(); 1279 while(results!=null) { 1280 // If the key exists in the map we add a new entry to it. 1281 if(resultsArray[results[1]]) { 1282 resultsArray[results[1]][resultsArray[results[1]].length] = results[2]; 1283 } else { 1284 resultsArray[results[1]] = new Array(); 1285 resultsArray[results[1]][0] = results[2]; 1286 } 1287 // We check for new data... 1288 results = regexExpr.exec(data); 1289 } 1290 // Finally, we have eval the array, so we can return it. 1291 return resultsArray; 1292} 1293 1294/**
1295 * Función que inicializa la librerÃa que convierte tablas de datos a gráficas... 1296 * @memberOf Init 1297 */ 1298function initVisualizeCharts() { 1299 loadCSS(_rootWeb+'/javaScript/visualizeCharts/css/visualize.css'); 1300 if(typeof ($.fn.visualize) == "undefined") { 1301 if($.browser.msie) { 1302 loadScript({ url: _rootWeb+'/javaScript/visualizeCharts/js/excanvas.js', success: function(){ 1303 loadScript({ url: _rootWeb+'/javaScript/visualizeCharts/js/jquery.visualize.js', success: function(){ 1304 loadVisualizeCharts(); 1305 }}); 1306 }}); 1307 }else{ 1308 loadScript({ url: _rootWeb+'/javaScript/visualizeCharts/js/jquery.visualize.js', success: function(){ 1309 loadVisualizeCharts(); 1310 }}); 1311 } 1312 } 1313 else { 1314 loadVisualizeCharts(); 1315 } 1316} 1317 1318/** 1319 * Función que convierte las posibles tablas de datos que pudiera tener la página a gráficas... 1320 * @memberOf Init 1321 */ 1322function loadVisualizeCharts() { 1323 1324 // Examinamos cuantas gráficas tenemos que generar 1325 var cmCharts = $("a[rel^='cmChart'],a[data-rel^='cmChart']"); 1326 if(cmCharts.length > 0) { 1327 cmCharts.each(function() { 1328 var table = $(this).next('table'); 1329 if(table.length > 0) { 1330 var theRel = $(this).attr("rel"); 1331 if(!theRel) theRel = $(this).attr("data-rel"); 1332 theRel = theRel.replace(/\"/g,'"'); // Necesario para IE 1333 var theRelAttribs = decodeMap(theRel); 1334 var _chartType = null, _chartTheme = null, _showDataTable = false, _title = null, _chartParseDirection = null; 1335 var _width = table.width(), _height = table.height(); 1336 1337 // Recogemos los parámetros del rel 1338 if(theRelAttribs["type"] != undefined) 1339 _chartType = theRelAttribs["type"][0]; 1340 1341 if(theRelAttribs["theme"] != undefined) 1342 _chartTheme = theRelAttribs["theme"][0]; 1343 1344 if(theRelAttribs["parseDirection"] != undefined) 1345 _chartParseDirection = theRelAttribs["parseDirection"][0]; 1346 1347 if(theRelAttribs["width"] != undefined) 1348 _width = parseInt(theRelAttribs["width"][0], 10); 1349 1350 if(theRelAttribs["height"] != undefined) 1351 _height = parseInt(theRelAttribs["height"][0], 10); 1352 1353 if(theRelAttribs["showdatatable"] != undefined && theRelAttribs["showdatatable"][0] == "true") 1354 _showDataTable = true; 1355 1356 if($("caption", table).length > 0 && $("caption", table).text() != '') 1357 _title = $("caption", table).text(); 1358 else if(table.attr("summary") + '' != '') 1359 _title = table.attr("summary"); 1360 1361 // Ocultamos la tabla de datos si hace falta 1362 if(!_showDataTable) table.hide(); 1363 1364 // Generamos y adjuntamos la gráfica justo después de la tabla de datos 1365 try { 1366 //console.log('type:'+_chartType+' theme:'+_chartTheme+' width:'+_width+' height:'+_height+' title:'+_title +' parseDirection:'+_chartParseDirection); 1367 table.visualize({ type: _chartType, theme: _chartTheme, width: _width, height: _height, title: _title, parseDirection: _chartParseDirection }); 1368 } 1369 catch (ex) { 1370 } 1371 } 1372 }); 1373 } 1374} 1375 1376/** 1377 * Función que se encarga de asociar eventos a los items del cubo OLAP para marcar cuando se abren y ocultan elementos 1378 * expandibles 1379 * 1380 * @memberOf Init 1381 */ 1382function manageOlapExpandables() { 1383 1384 $('.olapExpandable','.olapCalendarDates').click(function() { 1385 $(this).toggleClass('olapOpened'); 1386 }); 1387 1388} 1389 1390/** 1391 * Evento ready 1392 * @memberOf Init 1393 */ 1394$(document).ready(function () { 1395 1396 // Registramos todos los scripts/css actualmente cargados para no volverlos a cargar de forma dinámica... 1397 $("script,link[rel='stylesheet']").each(function() { 1398 var _src = ''; 1399 if(this.nodeName.toLowerCase() == 'link') { 1400 _src = $(this).attr("href"); 1401 } else if(this.nodeName.toLowerCase() == 'script') { 1402 _src = $(this).attr("src"); 1403 } 1404 if(_src && _src != '') { 1405 _src = prepareLoadedFile(_src); 1406 loadedFiles[_src] = true; 1407 loadedFiles[_src+'.success'] = true; 1408 } 1409 }); 1410 1411 // comprobamos si necesitamos el plugin prettyPhoto para imágenes, videos... 1412 if($("a[rel^='prettyPhoto']:not(.cmPhotoSwipe),a[data-rel^='prettyPhoto']:not(.cmPhotoSwipe)").length > 0){ 1413 initPrettyPhoto(); 1414 } 1415
1416 // comprobamos si necesitamos el plugin photoSwipe para imágenes, videos... 1417 if($("a.cmPhotoSwipe").length > 0){ 1418 initPhotoSwipe(); 1419 } 1420 1421 if($('.olapCalendarDates').length>0) { 1422 manageOlapExpandables(); 1423 } 1424 1425 // comprobamos si necesitamos el plugin flowPlayer para videos... 1426 if($('a.cmAutoVideo,a.cmAutoAudio,a.cmAutoVideoNoAlt').length > 0 || $("#videoteca,#videotecaPlayer").length > 0) { 1427 initFlowPlayer(); 1428 }; 1429 1430 // función que inicializa los calendarios... 1431 initCalendarios(); 1432 1433 // comprobamos si necesitamos el plugin que convierte tablas de datos a gráficas... 1434 if($("a[rel^='cmChart'],a[data-rel^='cmChart']").length > 0) { 1435 initVisualizeCharts(); 1436 } 1437 1438 // Determinamos si estamos en _preview 1439 if(typeof(_currentTemplate) == 'string' && _currentTemplate == '/preview') { 1440 $('body').css('position','relative'); 1441 $('body').prepend('<div class="coverWrapper"></div>'); 1442 } 1443 1444 // Inicializamos el plugin de localización si es necesario 1445 initProxiaLocation(); 1446 initProxiaSearch(); 1447 initCsrf(); 1448 1449 // Inicializamos xforms sólo si existe algún formulario en la página, aprovechamos para inicializar el plugin de calendario 1450 var $forms = $('form.form-container'); 1451 if($forms.length > 0) { 1452 // Si no existe bootstrap en la web lo cargamos de forma dinámica 1453 if(typeof($.fn.modal) === 'undefined') { 1454 if(typeof(_bootstrapPath) != 'string') { 1455 _bootstrapPath = _rootWeb+'/javaScript/bootstrap'; 1456 } 1457 loadCSS(_bootstrapPath+'/css/bootstrap.min.css'); 1458 loadCSS(_bootstrapPath+'/css/bootstrap-theme.min.css'); 1459 loadScript({ url: _bootstrapPath+'/js/bootstrap.min.js', success: function(){ 1460 $.fn.bstooltip = $.fn.tooltip.noConflict(); // Para evitar conflictos con jquery-ui 1461 initXForms($forms, initDateTimePickers); 1462 }}); 1463 } else { 1464 initXForms($forms, initDateTimePickers); 1465 } 1466 } else { 1467 initDateTimePickers(); 1468 } 1469 1470 // Nos aseguramos de que todos los tooltip y popover se cierren con ESC 1471 document.addEventListener('keydown', function(e) { 1472 if ( typeof ( $.fn.bstooltip ) === 'function' ) { 1473 $.fn.tooltip = $.fn.bstooltip; 1474 } 1475 1476 if ( typeof ( $.fn.tooltip ) !== 'function' ) return; 1477 if ('Escape' === e.key) { 1478 const $openTooltips = $('.tooltip'); 1479 const $openPopovers = $('.popover'); 1480 1481 if ($openPopovers.length || $openTooltips.length) { 1482 e.stopPropagation(); 1483 $openTooltips.tooltip('hide'); 1484 $openPopovers.popover('hide'); 1485 } 1486 } 1487 }, true); 1488}); 1489 1490/** 1491 * Inicializamos el token CSRF en todos los formularios y lo activamos a nivel de todas las peticiones AJAX 1492 */ 1493function initCsrf() { 1494 var csrf = GetCookie('_proxia_csrf'); 1495 if(csrf) { 1496 // Vamos a añadir a todos los formularios de la página que tengan un actionCode definido el valor 1497 // de la cookie de CSRF 1498 $('form').each(function(i) { 1499 var $form = $(this); 1500 if(!$form.attr('method') || $form.attr('method').toUpperCase()=== 'GET') return; 1501 1502 // Ahora vemos si tenemos un aributo de tipo actionCode 1503 if($('[name="actionCode"]',$form).length > 0) { 1504 // Tenemos que añadir el atributo de CSRF a la petición. 1505 var _csrf = $('<input type="hidden" name="__proxia_csrf" value="'+csrf+'"/>'); 1506 $form.append(_csrf); 1507 } 1508 }); 1509 } 1510 // Para que todas las funciones AJAX lo incluyan... tenemos que leerlo siempre antes 1511 // de envÃa. 1512 $( document ).ajaxSend(function( event, jqxhr, settings ) { 1513 var csrf = GetCookie('_proxia_csrf'); 1514 if(csrf) { 1515 jqxhr.setRequestHeader('X-Proxia-CSRF', csrf) 1516 } 1517 }); 1518} 1519 1520/** 1521 * Inicializamos el plugin de localización si es necesario 1522 * @memberOf Init 1523 */ 1524function initProxiaLocation() { 1525 if(typeof(locationSettings) == "object" && $('input[data-location]').length > 0) { 1526 loadCSS(_rootWeb+'/css/jquery-ui-theme/jquery-ui-theme.min.css'); 1527 loadScript({ url: _rootWeb+'/javaScript/jquery-ui.min.js', success: function(){ 1528 loadScript({ url: _rootWeb+'/javaScript/jquery.ui.touch-punch.min.js', success: function(){ 1529 loadScript({ url: _rootWeb+'/javaScript/proxia.location.js', success: function(){ 1530 $(document).proxiaLocation(locationSettings); 1531 }}); 1532 }}); 1533 }}); 1534 } 1535} 1536 1537/** 1538 * Inicializamos el plugin de busqueda predictiva si es necesario 1539 * @memberOf Init 1540 */ 1541function initProxiaSearch() {
1542 var $inputs = $('input[data-search="true"]'); 1543 if($inputs.length > 0) { 1544 loadCSS(_rootWeb+'/css/jquery-ui-theme/jquery-ui-theme.min.css'); 1545 loadScript({ url: _rootWeb+'/javaScript/jquery-ui.min.js', success: function(){ 1546 loadScript({ url: _rootWeb+'/javaScript/jquery.ui.touch-punch.min.js', success: function(){ 1547 proxiaSearchPredictive($inputs); 1548 }}); 1549 }}); 1550 } 1551} 1552 1553/** 1554 * Inicializa los formularios pasados como parámetro y carga las librerÃas css/js necesarias 1555 * @param {array} $forms - Array de formularios 1556 * @param callback - El callback 1557 * @memberOf Init 1558 */ 1559function initXForms($forms, callback) { 1560 var doInitForms = function() { 1561 // Independientemente de que carge o no el custom tengo que inicializar los formularios 1562 $forms.each(function() { 1563 xforms.init($(this)); 1564 if(typeof(callback) == 'function') callback($forms); 1565 }); 1566 } 1567 1568 loadCSS(_rootWeb+'/css/proxia.xforms.css'); 1569 loadScript({ url: _rootWeb+'/javaScript/proxia.xforms.js', success: function(){ 1570 loadScript({ url: _rootWeb+'/javaScript/moment/min/moment.min.js', success: function(){ 1571 loadScript({ url: _rootWeb+'/javaScript/moment/locale/'+xforms.getMomentLocale(xforms.locale)+'.js', success: function(){ 1572 loadScript({ url: _rootWeb+'/javaScript/xpath.min.js', success: function(){ 1573 var _xformsPath = _rootWeb+'/javaScript/proxia.xforms.custom.js'; 1574 if(typeof(xformsCustomPath)!=='undefined' && xformsCustomPath) { 1575 _xformsPath = xformsCustomPath; 1576 } 1577 // Puede que exista o no exista el fichero de custom (si da error lo ignoramos) 1578 loadScript({ url: _xformsPath, success: function(){ 1579 doInitForms(); 1580 }, error: function(){ 1581 doInitForms(); 1582 }}); 1583 1584 }}); 1585 }}); 1586 }}); 1587 }}); 1588} 1589 1590 1591 1592// Cargamos de forma dinámica unos estilos css relacionados con el componente de paginación con scroll infinito 1593if(typeof jQuery !== 'undefined' && $('#cmAutoPaginationStyle').length == 0) { 1594 $("head").append(' \ 1595 <style type="text/css" id="cmAutoPaginationStyle"> \ 1596 .cmAutoPagination .cmContentItem { visibility: hidden; } \ 1597 .cmAutoPagination .cmNavigation { display: none; } \ 1598 </style> \ 1599 '); 1600} 1601 1602/** 1603 * Inicializamos los componentes de paginación con scroll infinito 1604 * @memberOf Init 1605 */ 1606function initWayPoints() { 1607 var $items = $("ul.cmAutoPagination,div[class*='animation-']"); 1608 if($items.length > 0) { 1609 if(_compatibilityMode < 2) loadCSS(_rootWeb+'/css/animate.css'); 1610 if(typeof(Waypoint) != 'function') { 1611 loadScript({ url: _rootWeb+'/javaScript/waypoints/jquery.waypoints.min.js', success: function(){ 1612 loadScript({ url: _rootWeb+'/javaScript/waypoints/shortcuts/inview.min.js', success: function(){ 1613 afterInitWayPoints($items); 1614 }}); 1615 }}); 1616 } else { 1617 afterInitWayPoints($items); 1618 } 1619 } 1620} 1621 1622function afterInitWayPoints($items) { 1623 initAnimationEffects($items); 1624 initAutoPagination($items); 1625} 1626 1627/** 1628 * Inicializa las animaciones css3 para cada uno de los componentes 1629 * @param {array} $items - Array de items a procesar 1630 * @memberOf Init 1631 */ 1632function initAnimationEffects($items) { 1633 $items.filter("[class*='animation-']").each(function() { 1634 var $this = $(this); 1635 var className = $this.attr("class"); 1636 var results = className.match(/animation-([_a-zA-Z0-9-]+)/gm); 1637 if(results != null && results.length > 0) { 1638 $this.data("animationClasses", results); 1639 var myWaypoint = new Waypoint.Inview({ 1640 element: $this.get(0), 1641 enter: function(direction) { 1642 var animationClasses = $(this.element).data("animationClasses"); 1643 if(animationClasses != null && animationClasses.length > 0) { 1644 $(this.element).addClass('animated'); 1645 for(var i = 0; i < animationClasses.length; i++) { 1646 var classEffect = animationClasses[i]; 1647 var animationEnd = 'webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend'; 1648 $(this.element).queue(function (next) { 1649 $(this).addClass(classEffect.replace('animation-', '')).removeClass(classEffect); 1650 $(this).one(animationEnd, function() { 1651 $(this).removeClass(classEffect.replace('animation-', '')); 1652 if(i == animationClasses.length - 1) { 1653 $(this).removeClass('animated'); 1654 myWaypoint.destroy(); 1655 } 1656 next(); 1657 }); 1658 }); 1659 } 1660 } 1661 } 1662 }); 1663 } 1664 }); 1665} 1666 1667/** 1668 * Inicializa el soporte de paginacion con scroll infinito en modo moderno 1669 * @memberOf Init 1670 */ 1671function initEndlessNavigation() { 1672 // Tenemos que localizar los eventos que tienen asociado la clase CSS .cmAutoNavigation de tipo A 1673 $('a.cmAutoNavigation').each(function() { 1674 // Cargamos la lista en la que mostramos los datos que tenemos asociados. 1675 var $link = $(this); 1676 var $ul = $link.closest('.cmNavigation').siblings('ul.cmContentList'); 1677 var $container = $ul.closest("div.cmBodyAbstractContent[data-beanname],div.cmBodyContentChildrens[data-beanname],div.cmSameParentContentsBox[data-beanname],div.autoRelatedBox[data-beanname]"); 1678 if($container.length == 0) return; 1679 1680 1681 var url = $container.data('url'); 1682 var beanname = $container.data('beanname'); 1683 var elements = $container.data("elements"); 1684 var columns = $container.data("columns"); 1685 var animated = $container.data("animated");
1686 var delay = $container.data("delay"); 1687 var nshow = elements; // Elementos por página 1688 var totalLength; 1689 if ($("li.cmContentItem", $ul).length < nshow){ 1690 totalLength= $("li.cmContentItem", $ul).length; 1691 }else{ 1692 totalLength= $container.data("totalLength"); 1693 } 1694 1695 // Initializamos variables de paginación 1696 $container.data("nshow", nshow); 1697 $container.data("position", 0); 1698 1699 if($ul.nextAll("div.spinner").length == 0) { 1700 $ul.after('<div class="spinner" style="display:none;"><span class="fa fa-4x fa-refresh fa-spin"></span></div>'); 1701 } 1702 1703 // Cuando hagamos click sobre el elemento es cuando tenemos que pintar los daots y además 1704 $link.click(function(e) { 1705 e.preventDefault(); 1706 1707 // Preincrementamos para tener los resultados que queremos mostrar. 1708 $container.data("position", $container.data("position") + $container.data("nshow")); 1709 1710 1711 // Generamos la URL de nuevo, por JavaScript, no nos hace falta otra cosa... 1712 var ajaxUrl; 1713 if ($container.data("parameters")){ 1714 ajaxUrl = url; 1715 ajaxUrl += '?' + $container.data("parameters"); 1716 }else{ 1717 ajaxUrl = _rootWeb + '/cm/' + url; 1718 ajaxUrl += '?containerShown=false'; 1719 } 1720 ajaxUrl += '&position.'+beanname+'='+$container.data("position"); 1721 ajaxUrl += '&nshow.'+beanname+'='+$container.data("nshow"); 1722 1723 // Activamos el spinner... 1724 $ul.nextAll("div.spinner").show(); 1725 // Hacemos la llamada por Ajax 1726 $.ajax({ 1727 type: 'GET', 1728 url: ajaxUrl, 1729 dataType: 'text', 1730 success: function(html) { 1731 var $html = $(html); 1732 1733 // Tenemos que recalcuar las expresiones de fecha que aplican 1734 if(typeof resolveDateExpressions === 'function') { 1735 resolveDateExpressions($html); 1736 } 1737 1738 1739 1740 var $items = $("li.cmContentItem", $html); 1741 var timeout = 0; 1742 1743 if($items.length > 0) { 1744 $items.each(function(index) { 1745 var $li = $(this); 1746 if(animated) { 1747 animatePaginationItem($ul, $li, animated, delay ? timeout+=delay : 0); 1748 } else { 1749 $li.css("visibility", "visible"); 1750 } 1751 1752 $ul.append($li); 1753 if(index === 0) { 1754 $('a',$li).attr('tabindex',0); 1755 $('a',$li).focus(); 1756 } 1757 }); 1758 } 1759 // Si tenemos el caso de que el nº de items es menor que el nº de elementos pedidos, es posible que estemos 1760 // en una búsqueda y el totalLenth sea estimado. En ese caso, lo seteamos al valor total. 1761 if ($items.length < $container.data("nshow")){ 1762 totalLength = $("li.cmContentItem", $ul).length; 1763 } 1764 1765 1766 1767 $ul.nextAll("div.spinner").hide(); 1768 1769 // Ejecutamos el resize de la ventana por si tiene que ejecutarse algún plugin 1770 setTimeout(function() { 1771 $(window).trigger("resize"); 1772 }, timeout); 1773 1774 // Cargamos los botones del wizard, si está cargado 1775 if(typeof(checkContentPermissions) == 'function') { 1776 checkContentPermissions(); 1777 } 1778 1779 var nshow = $container.data("nshow"); 1780 var position = $container.data("position"); 1781 1782 // Tenemos que actualizar los datos que tenemos en pantalla, a la posición 1783 if(position + nshow >= totalLength) { 1784 // Ocultamos el link. 1785 $link.closest('.cmNavigation').hide(); 1786 } 1787 1788 // Tenemos que calcular cambios en el tamaño de posibles elementos 1789 // que hayan aparecido. 1790 if(typeof adjustCSSCutTextHeights === 'function') { 1791 adjustCSSCutTextHeights($ul[0],false); // Forzamos el recálculo. 1792 } 1793 1794 1795 return; 1796 } 1797 }); 1798 1799 }); 1800 }); 1801} 1802 1803/** 1804 * Ajusta las alturas de todos los elementos de la página, lo ajustamos con un pequeño timeout, 1805 * se puede personalizar en función del lineHeight del proyecto y una función de cálculo 1806 * repetido de after para personalizr situaciones no contempladas. 1807 * 1808 * @param rootNode El nodo raiz o todo el documento si es undefined, null, cadena vacÃa 1809 * @param adaptative Si estamos en un cambio adaptativo 1810 */ 1811function adjustCSSCutTextHeights(rootNode,adaptative) { 1812 if(rootNode === undefined || rootNode === null || rootNode === '') rootNode = document.documentElement; 1813 1814 if($('#lineHeightChecker').length == 0) { 1815 var n = document.createElement('div'); 1816 n.style.lineHeight = 1; 1817 n.style.fontSize = '10px'; 1818 n.setAttribute('id', 'lineHeightChecker'); 1819 document.body.appendChild(n); 1820 } 1821 var elem = document.getElementById('lineHeightChecker'); 1822 var oldLineHeight = elem.dataset.lineHeight; 1823 var lineHeightBase = 1.428571429; // Variable por defecto 1824 if(typeof _projectLineHeight !=='undefined' && _projectLineHeight) { 1825 lineHeightBase = _projectLineHeight; 1826 } 1827 1828 var lheight = window.getComputedStyle(document.getElementById('lineHeightChecker')).lineHeight; 1829 1830 1831 if(rootNode!=document.documentElement || adaptative || (lheight != '10px' && oldLineHeight===undefined) || (oldLineHeight!==undefined && oldLineHeight!=lheight)) { 1832 var redefinedLineHeight = parseInt(lheight)/10; 1833 1834 // Tenemos que iterar por todos los elementos para calcular la altura 1835 var whatToFind = { 1836 property: "text-overflow", 1837 values: ["ellipsis"] 1838 }; 1839 1840 var walker = 1841 document.createTreeWalker(rootNode, NodeFilter.SHOW_ELEMENT, 1842 function(el) { 1843 var style = getComputedStyle(el)[whatToFind.property]; 1844 return whatToFind.values.includes(style) 1845 ? NodeFilter.FILTER_ACCEPT 1846 : NodeFilter.FILTER_SKIP; 1847 }); 1848 1849 1850 while (walker.nextNode()) { 1851 var n = walker.currentNode; 1852 if(adaptative || n.dataset.originalHeight === undefined || n.dataset.originalHeight === '') { 1853 if(adaptative) n.style.height = null; 1854 n.dataset.originalHeight = parseInt(getComputedStyle(n)['height']); 1855 } 1856 if(redefinedLineHeight === 1) { 1857 n.style.height = null; 1858 } else { 1859 var fontSize = parseInt(getComputedStyle(n)['fontSize']); 1860 var lines = Math.round(n.dataset.originalHeight/(fontSize*lineHeightBase)); 1861 if(redefinedLineHeight > 1) { 1862 lines++; 1863 n.style.setProperty('-webkit-line-clamp',lines); 1864 } 1865 var newHeight = redefinedLineHeight*fontSize*lines; 1866 if(redefinedLineHeight!==1) { 1867 if(parseInt(getComputedStyle(n)['lineHeight']) != fontSize*redefinedLineHeight) { 1868 n.style.setProperty('line-height',fontSize*redefinedLineHeight+'px','important'); 1869 } else { 1870 n.style.lineHeight = undefined; 1871 n.style.setProperty('-webkit-line-clamp',undefined); 1872 } 1873 } else { 1874 n.style.lineHeight = null; 1875 } 1876 n.style.height = newHeight + 'px'; 1877 } 1878 } 1879 elem.dataset.lineHeight = lheight; 1880 1881 // Indicamos al cuerpo que tenemos un userDefinedLineHeight 1882 if(redefinedLineHeight===1) { 1883 $('body').removeClass('userDefinedLineHeight'); 1884 } else { 1885 $('body').addClass('userDefinedLineHeight'); 1886 } 1887 1888 // Para que ejecute una función despues de resetear el tamaño de lÃnea 1889 if(typeof customAfterSetHeight === 'function') { 1890 customAfterSetHeight(redefinedLineHeight); 1891 } 1892 } 1893 1894 // Ejecutamos el chequeo cada 500 ms... por si se meten a mano o se modifican los estilos 1895 // en cualqueir momento. 1896 setTimeout(function() { 1897 adjustCSSCutTextHeights(); 1898 },500); 1899} 1900 1901 1902/** 1903 * Inicializa cada uno de los componentes de paginación con scroll infinito 1904 * @param {array} $autoPagination - Array de componentes de paginación 1905 * @memberOf Init 1906 */ 1907function initAutoPagination($autoPagination) { 1908 $autoPagination.filter("ul.cmAutoPagination").each(function() { 1909 var $ul = $(this); 1910 1911 if ($ul.data("initialized")){ 1912 return; 1913 } 1914 var $container = $ul.closest("div.cmBodyAbstractContent[data-beanname],div.cmBodyContentChildrens[data-beanname]"); 1915 1916 if($container.length == 0) return; 1917 1918 var elements = $container.data("elements"); 1919 var columns = $container.data("columns"); 1920 var animated = $container.data("animated");
1921 var delay = $container.data("delay"); 1922 var manual = $container.data("manual") || $container.hasClass("manual-scroll"); 1923 var nshow = elements; // Elementos por página 1924 1925 // Si estamos en una búsqueda, es posible que el totalLength sea estimado. En este caso lo seteamos si en nº de elementos 1926 // obtenidos es menor qeu el nº de elementos pedidos 1927 var totalLength; 1928 if ($("li.cmContentItem", $ul).length < nshow){ 1929 totalLength= $("li.cmContentItem", $ul).length; 1930 }else{ 1931 totalLength= $container.data("totalLength"); 1932 } 1933 1934 // Animamos los elementos actuales 1935 var $items = $("> li.cmContentItem", $ul); 1936 var timeout = 0; 1937 $items.each(function() { 1938 var $li = $(this); 1939 if(animated) { 1940 animatePaginationItem($ul, $li, animated, delay ? timeout+=delay : 0); 1941 } else { 1942 $li.css("visibility", "visible"); 1943 } 1944 }); 1945 1946 // No se pagina, ya que se muestran todos 1947 if(nshow == -1 || nshow > totalLength) { 1948 if(manual) { 1949 var $manualSelector = $container.data("manualSelector") || $(".contentViewMore", $container); 1950 if($manualSelector && $manualSelector.length > 0) { 1951 $manualSelector.hide(); 1952 } 1953 } 1954 return; 1955 } 1956 1957 setTimeout(function() { 1958 1959 // Initializamos variables de paginación 1960 $container.data("nshow", nshow); 1961 $container.data("position", 0); 1962 1963 // Avance manual 1964 if(manual) { 1965 1966 var $manualSelector = $container.data("manualSelector") || $(".contentViewMore", $container); 1967 if($manualSelector && $manualSelector.length > 0) { 1968 $manualSelector.show(); 1969 var $link = $container.data("manualSelector") || $("> a", $manualSelector); 1970 if($link && $link.length > 0) { 1971 $link.click(function(e) { 1972 e.preventDefault(); 1973 $container.data("position", $container.data("position") + $container.data("nshow")); 1974 getAutoPaginationItems($ul, $container); 1975 }); 1976 } 1977 } 1978 1979 } else { 1980 1981 // Initializamos la paginación con scroll infinito 1982 var waypoint = new Waypoint({ 1983 element: $ul.get(0), 1984 handler: function(direction) { 1985 if(direction == 'down') { 1986 1987 // Si tenemos el layoutManager activado, desactivamos la auto-paginación 1988 if($('body').hasClass("layoutManagerEnabled") || $('body').hasClass("cmWizardEditMode")) return; 1989 1990 $container.data("position", $container.data("position") + $container.data("nshow")); 1991 getAutoPaginationItems($ul, $container); 1992 } 1993 }, 1994 offset: 'bottom-in-view' 1995 }); 1996 $container.data("waypoint", waypoint); 1997 } 1998 1999 if($ul.nextAll("div.spinner").length == 0) { 2000 $ul.after('<div class="spinner" style="display:none;"><span class="fa fa-4x fa-refresh fa-spin"></span></div>'); 2001 } 2002 2003 }, timeout); 2004 2005 // Por último, lo marcamos como inicializado para que no se inicialice 2 veces 2006 $ul.data("initialized","true"); 2007 }); 2008} 2009 2010/** 2011 * Función que realiza una búsqueda de elementos a paginar por ajax 2012 * @param $ul - Listado 2013 * @param {object} $container - Contenedor de parametros y ajustes 2014 * @returns {boolean} 2015 * @memberOf Init 2016 */ 2017function getAutoPaginationItems($ul, $container) { 2018 2019 var url = $container.data("url"); 2020 var parameters = $container.data("parameters"); 2021 var beanname = $container.data("beanname"); 2022 var totalLength = $container.data("totalLength"); 2023 var animated = $container.data("animated");
2024 var delay = $container.data("delay"); 2025 var manual = $container.data("manual") || $container.hasClass("manual-scroll"); 2026 2027 var ajaxUrl; 2028 2029 if (parameters){ 2030 ajaxUrl = url; 2031 ajaxUrl += '?' + parameters; 2032 }else{ 2033 ajaxUrl = _rootWeb + '/cm/' + url; 2034 ajaxUrl += '?containerShown=false'; 2035 } 2036 2037 ajaxUrl += '&position.'+beanname+'='+$container.data("position"); 2038 ajaxUrl += '&nshow.'+beanname+'='+$container.data("nshow"); 2039 2040 $ul.nextAll("div.spinner").show(); 2041 2042 $.ajax({ 2043 type: 'GET', 2044 url: ajaxUrl, 2045 dataType: 'text', 2046 success: function(html) { 2047 var $html = $(html); 2048 var $items = $("li.cmContentItem", $html); 2049 var timeout = 0; 2050 2051 if($items.length > 0) { 2052 $items.each(function() { 2053 var $li = $(this); 2054 if(animated) { 2055 animatePaginationItem($ul, $li, animated, delay ? timeout+=delay : 0); 2056 } else { 2057 $li.css("visibility", "visible"); 2058 } 2059 $ul.append($li); 2060 }); 2061 } 2062 2063 // Si tenemos el caso de que el nº de items es menor qeu el nº de elementos pedidos, es posible qeu estemos 2064 // en una búsqueda y el totalLenth sea estimado. En ese caso, lo seteamos al valor total. 2065 if ($items.length < $container.data("nshow")){ 2066 totalLength = $("li.cmContentItem", $ul).length; 2067 } 2068 2069 $ul.nextAll("div.spinner").hide(); 2070 2071 var fn = $container.data("manualCallback"); 2072 if(typeof(fn) == 'function') { 2073 fn($ul, $container); 2074 } 2075 2076 // Ejecutamos el resize de la ventana por si tiene que ejecutarse algún plugin 2077 setTimeout(function() { 2078 $(window).trigger("resize"); 2079 }, timeout); 2080 2081 // Cargamos los botones del wizard, si está cargado 2082 if(typeof(checkContentPermissions) == 'function') { 2083 checkContentPermissions(); 2084 } 2085 2086 var nshow = $container.data("nshow"); 2087 var position = $container.data("position"); 2088 2089 if(position + nshow >= totalLength) { 2090 // Ya hemos mostrado todo 2091 if($ul.nextAll("div.no-results").length == 0) { 2092 $ul.nextAll("div.spinner").after('<div class="no-results"></div>'); 2093 } 2094 if(!manual) { 2095 var waypoint = $container.data("waypoint"); 2096 waypoint.destroy(); 2097 } else { 2098 var $manualSelector = $container.data("manualSelector") || $(".contentViewMore", $container); 2099 if($manualSelector && $manualSelector.length > 0) $manualSelector.hide(); 2100 } 2101 return; 2102 } 2103 2104 if(!manual) { 2105 // Actualizamos las posiciones de waypoint 2106 Waypoint.refreshAll(); 2107 } 2108 } 2109 }); 2110 2111 return false; 2112} 2113 2114/** 2115 * Función que aplica un efecto css a un elemento de la paginación 2116 * @param $ul 2117 * @param $li - Objeto en cuestión a aplicar el efecto 2118 * @param {string} animated - Animación css clase 2119 * @param {number} timeout - Tiempo para el delay de la animación 2120 * @memberOf Init 2121 */ 2122function animatePaginationItem($ul, $li, animated, timeout) { 2123 if(!animated) return; 2124 // Usamos visibility para preservar el espacio 2125 $li.css("visibility", "hidden"); 2126 setTimeout(function() { 2127 $li.css("visibility", "visible"); 2128 // Realizamos la animación 2129 $li.addClass("animated " + animated); 2130 // Una vez acabada quitamos los css 2131 $li.one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', function() { 2132 $(this).removeClass('animated ' + animated); 2133 }); 2134 }, timeout); 2135} 2136 2137/** 2138 * Función que proporciona el mecanismo necesario para desarrollar menús para páginas OnePage con el uso de anclas de tipo #![ID] en los enlaces de los menús. 2139 * @param $selector Los distintos menús con anclas de tipo #![ID] 2140 * @param [$header] - Selector de la cabecera fixed si tenemos. Este parámetro es opcional. 2141 * @memberOf Init 2142 */ 2143function initScrollLink($selector, $header) { 2144 2145 var header = false;
2146 if($header && $header.length > 0) header = $header.selector; 2147 2148 var getHeaderHeight = function() { 2149 var height = 0; 2150 if(header) { 2151 height = $(header).outerHeight(); 2152 } 2153 return height; 2154 } 2155 2156 var getHeaderBorder = function() { 2157 var borderWidth = 0; 2158 if(header) { 2159 borderWidth += parseInt($(header).css("border-top-width"), 10); 2160 borderWidth += parseInt($(header).css("border-bottom-width"), 10); 2161 } 2162 return borderWidth; 2163 } 2164 2165 var onScrollLink = function() { 2166 var scrollPos = $(document).scrollTop() + getHeaderHeight(); 2167 $selector.each(function() { 2168 var currLink = $(this); 2169 var attrHref = currLink.attr("href").replace('!',''); 2170 if(attrHref.indexOf('#') != -1) { 2171 var selector = attrHref.substring(attrHref.indexOf('#')); 2172 var $refElement = selector == '#' ? $('body') : $(selector); 2173 if($refElement.length == 0) return; 2174 2175 if((selector == '#' && $(document).scrollTop() == 0) || 2176 (selector != '#' && $refElement.length > 0 && $refElement.offset().top <= scrollPos && 2177 $refElement.offset().top + $refElement.outerHeight() > scrollPos)) { 2178 2179 currLink.addClass("link-active"); 2180 } else{ 2181 currLink.removeClass("link-active"); 2182 } 2183 } 2184 }); 2185 }; 2186 2187 $(document).on("scroll.link", function() { onScrollLink($selector); }); 2188 2189 $(window).load(function(){ 2190 var locHash = window.location.hash; 2191 if(locHash.match("^#!")){ 2192 urlHash = locHash.replace('!',''); 2193 } 2194 var initialHeaderHeight = getHeaderHeight(); 2195 if(typeof(urlHash) != 'undefined' && urlHash != '#' && urlHash.length > 0) { 2196 $('html,body').stop().animate({ 2197 'scrollTop': $(urlHash).offset().top - getHeaderHeight() + getHeaderBorder() 2198 }, $(urlHash).offset().top / 3, 'swing', function() { 2199 // Si la altura de la cabecera cambia al hacer scroll, la ajustamos al final 2200 if(initialHeaderHeight != getHeaderHeight()) { 2201 $('html,body').stop().animate({ 2202 'scrollTop': $(urlHash).offset().top - getHeaderHeight() + getHeaderBorder() 2203 }); 2204 } 2205 }); 2206 } 2207 2208 $(document).trigger("scroll.link"); 2209 }); 2210 2211 var cleanURL = function(url) { 2212 2213 if(!url) return ''; 2214 2215 var pos1 = url.lastIndexOf('#'); 2216 if(pos1 != -1) url = url.substring(0, pos1); 2217 2218 var pos2 = url.lastIndexOf('?'); 2219 if(pos2 != -1) url = url.substring(0, pos2); 2220 2221 if(url.substring(url.length - 1) == '/') { 2222 url = url.substring(0, url.length - 1); 2223 } 2224 2225 return url; 2226 }; 2227 2228 //smoothscroll 2229 $selector.on('click.link', function (e) { 2230 2231 if(!this.hash) return; 2232 2233 // Si nos encontramos en una página distinta a la del enlace, no hacemos nada 2234 if(cleanURL(this.href) != cleanURL(location.href)) return; 2235 2236 $(document).off("scroll.link"); 2237 2238 $('a').each(function () { 2239 $(this).removeClass('link-active'); 2240 }) 2241 $(this).addClass('link-active'); 2242 2243 var hash = this.hash; 2244 var target = hash.replace('!',''); 2245 if(target == '#') { 2246 $target = $('body'); 2247 } else { 2248 $target = $(target); 2249 } 2250 if($target.length == 0) return; 2251 2252 e.preventDefault(); 2253 2254 var initialHeaderHeight = getHeaderHeight(); 2255 2256 $('html,body').stop().animate({ 2257 'scrollTop': $target.offset().top - getHeaderHeight() + getHeaderBorder() 2258 }, 600, 'swing', function() { 2259 // Si la altura de la cabecera cambia al hacer scroll, la ajustamos al final 2260 if(initialHeaderHeight != getHeaderHeight()) { 2261 $('html,body').stop().animate({ 2262 'scrollTop': $target.offset().top - getHeaderHeight() + getHeaderBorder() 2263 },200); 2264 } 2265 if(hash) window.location.hash = hash; 2266 $(document).on("scroll.link", function() { onScrollLink($selector); }); 2267 }); 2268 }); 2269} 2270 2271/**
2272 * Función utilizada para el árbol de etiquetas de los blogs 2273 * @param objSPAN 2274 * @memberOf Init 2275 */ 2276function toggleTreeNode(objSPAN) { 2277 if(objSPAN && objSPAN.style) objSPAN = $(objSPAN); 2278 if(objSPAN && objSPAN.hasClass("cmCategorizerImage")) { 2279 var objUL=objSPAN.parent().find("ul:first"); // El UL que contiene las subentradas 2280 var objIMG=objSPAN.find("img"); // La imagen del triángulo 2281 if(objUL.length > 0 && objIMG.length > 0) { 2282 var imgSrc = objIMG.attr("src"); 2283 if(objUL.hasClass("cmContentListRight")) { 2284 objIMG.attr("src",imgSrc.replace('Right','Down')); 2285 objIMG.attr("class","cmCategorizerImageDown"); 2286 objUL.attr("class","cmContentListDown"); 2287 } 2288 else { 2289 objIMG.attr("src",imgSrc.replace('Down','Right')); 2290 objIMG.attr("class","cmCategorizerImageRight"); 2291 objUL.attr("class","cmContentListRight"); 2292 } 2293 } 2294 } 2295} 2296 2297/** 2298 * Función utilizada para enviar un comentario dentro de una entrada de blog 2299 * @param {string} objForm - El blog al cual enviamos el comentario 2300 * @returns {boolean} 2301 * @memberOf Init 2302 */ 2303function sendBlogEntryComment(objForm) { 2304 var $objForm = $(objForm); 2305 if(dv2eeFormChecker(objForm,requiredAttsForSendMail,requiredAttsValsForSendMail)) { 2306 objForm.cmClientButtonSubmit.disabled = true; 2307 showWaitDialog('Enviando...'); 2308 // Recuperamos los textos multiidiomas (properties) por ajax 2309 $.ajax({ 2310 url: $objForm.attr("action"), 2311 type: $objForm.attr("method"), 2312 data: $objForm.serialize(), 2313 success: function(html) { 2314 hideWaitDialog(); 2315 objForm.cmClientButtonSubmit.disabled = false; 2316 $('.successComment').css('display','block'); 2317 $('.boxEntryComments form')[0].reset(); 2318 $('.boxEntryComments label').css('display','block'); 2319 if(_role == true){ 2320 location.reload(); 2321 } 2322 }, 2323 error: function (xhr, ajaxOptions, thrownError) { 2324 alert(thrownError + '\nError ' + xhr.status); 2325 } 2326 }); 2327 } 2328 2329 return false; 2330} 2331 2332/** 2333 * Función que inicializa los componentes de los blogs 2334 * @memberOf Init 2335 */ 2336function initBlogs() { 2337 // Blogs: Cerramos todos los nodos por fecha menos el primer año y mes 2338 var $treeByDate = $("#treeByDate"); 2339 if($treeByDate.length > 0 && $("span", $treeByDate).length > 2) { 2340 $("span", $treeByDate).each(function(index, val){ 2341 if(index >= 2) toggleTreeNode($(this)); 2342 }); 2343 } 2344 2345 // Blogs: Cerramos todos los nodos por etiqueta 2346 var $treeByLabels = $("#treeByLabels"); 2347 if($treeByLabels.length > 0 && $("span", $treeByLabels).length > 0) { 2348 $("span", $treeByLabels).each(function(index, val){ 2349 toggleTreeNode($(this)); 2350 }); 2351 } 2352} 2353 2354/** 2355 * Función que retorna la locale a utilizar 2356 * @param {string} locale - Cadena que se corresponde con el idioma a usar 2357 * @returns {*} 2358 * @memberOf Init 2359 */ 2360function getMomentLocale(locale) { 2361 // Incluimos la región en aquellos idiomas que estén localizados a nivel de región en el plugin bootstrap datetimepicker 2362 2363 if(locale == 'hy') return 'hy-am'; // Armenian 2364 if(locale == 'tl') return 'tl-ph'; // Tagalog/Filipino 2365 if(locale == 'zh') return 'zh-cn'; // Chinese 2366 if(locale == 'ar') return 'ar-tn'; // Tunisian Arabic 2367 // Y casos especiales 2368 // En proxia se utiliza para inglés británico el en_UK lo cual es incorrecto. 2369 // Para Java en = en_US = en_UK (aunque el en_UK sea un engendro un poco raro, yo creo que tira directamente al en y por tanto en_US) 2370 // y la única forma de poner el inglés británico es el en_GB 2371 // En javaScript tenemos: 2372 // en y en-us: que es el inglés americano 2373 // en-gb: que es el inglés británico 2374 if ( locale == 'en-UK') return 'en-us'; 2375 if ( locale == 'en') return 'en-us'; 2376 // Al en-gb no le tocamos 2377 // if(locale == 'en') return 'en-gb'; // English (Great Britain) 2378 return locale; 2379} 2380
2381/** 2382 * Función que inicializa el selector de fecha 2383 * @param {string} $container - Contenedor en el que se carga el selector 2384 * @param callbackOnChange 2385 * @memberOf Init 2386 */ 2387function initDateTimePickers($container, callbackOnChange) { 2388 2389 var selector = "input.cmParamDateType,input.cmParamDateTimeType,input.cmParamTimeType"; 2390 2391 if(!$container) $container = $(selector); 2392 2393 if($container.length > 0) { 2394 if(typeof(moment) != 'function') { 2395 loadScript({ url: _rootWeb+'/javaScript/moment/min/moment.min.js', success: function(){ 2396 loadScript({ url: _rootWeb+'/javaScript/moment/locale/'+getMomentLocale(_userLocaleLang)+'.js', success: function(){ 2397 initDateTimePickers($container, callbackOnChange); 2398 }}); 2399 }}); 2400 } else { 2401 if(typeof($.fn.datetimepicker) != 'function') { 2402 loadCSS(_rootWeb+'/javaScript/bootstrap-datetimepicker/css/bootstrap-datetimepicker.css'); 2403 loadScript({ url: _rootWeb+'/javaScript/bootstrap-datetimepicker/js/bootstrap-datetimepicker.js', success: function(){ 2404 initDateTimePickers($container, callbackOnChange); 2405 }}); 2406 } else { 2407 // Opciones comunes 2408 var pickerOptions = { 2409 locale: getMomentLocale(_userLocaleLang), 2410 allowInputToggle: true, 2411 useCurrent: false, 2412 keepOpen: false, 2413 debug: ($.browser.msie && $.browser.version <= 8) ? true : false, 2414 tooltips: { 2415 today: dtp_goToday, 2416 clear: dtp_clearSelection, 2417 close: dtp_closePicker, 2418 selectMonth: dtp_selectMonth, 2419 prevMonth: dtp_prevMonth, 2420 nextMonth: dtp_nextMonth, 2421 selectYear: dtp_selectYear, 2422 prevYear: dtp_prevYear, 2423 nextYear: dtp_nextYear, 2424 selectDecade: dtp_selectDecade, 2425 prevDecade: dtp_prevDecade, 2426 nextDecade: dtp_nextDecade, 2427 prevCentury: dtp_prevCentury, 2428 nextCentury: dtp_nextCentury, 2429 pickHour: dtp_pickHour, 2430 incrementHour: dtp_incrementHour, 2431 decrementHour: dtp_decrementHour, 2432 pickMinute: dtp_pickMinute, 2433 incrementMinute: dtp_incrementMinute, 2434 decrementMinute: dtp_decrementMinute, 2435 pickSecond: dtp_pickSecond, 2436 incrementSecond: dtp_incrementSecond, 2437 decrementSecond: dtp_decrementSecond, 2438 togglePeriod: dtp_togglePeriod, 2439 selectTime: dtp_selectTime, 2440 helpKey: dtp_helpKey, 2441 helpTitle: dtp_helpTitle, 2442 helpText: dtp_helpText 2443 } 2444 }; 2445 2446 $container.each(function() { 2447 var $input = $(this); 2448 2449 if($input.data("init")) return true; 2450 2451 if(!$input.is("input")) { 2452 initDateTimePickers($(selector, $input), callbackOnChange); 2453 return true; 2454 } 2455 2456 var dateFormat = $input.data("dateFormat") ? $input.data("dateFormat") : dtp_dateFormat.replace(/-/g, '/'); // En Proxia se tratan las fechas siempre con barras 2457 var timeFormat = $input.data("timeFormat") ? $input.data("timeFormat") : dtp_timeFormat; 2458 2459 if($input.hasClass("cmParamDateType")) { 2460 $input.datetimepicker($.extend(pickerOptions, { format: dateFormat })); 2461 } 2462 2463 if($input.hasClass("cmParamDateTimeType")) { 2464 $input.datetimepicker($.extend(pickerOptions, { format: dateFormat + ' ' + timeFormat })); 2465 } 2466 2467 if($input.hasClass("cmParamTimeType")) { 2468 $input.datetimepicker($.extend(pickerOptions, { format: timeFormat })); 2469 } 2470 2471 if(typeof(callbackOnChange) == 'function') { 2472 $input.on("dp.change", callbackOnChange); 2473 } 2474 2475 var $button = $input.next("button,.btn").first(); 2476 if($button.length == 0) $button = $input.prev("button,.btn").first(); 2477 if($button.length == 0) $button = $("button,.btn", $input.parent()).first(); 2478 if($button.length == 0) $button = $("button,.btn", $input.parent().parent()).first(); 2479 if($button.length > 0) { 2480 $button.removeAttr("onclick").removeAttr("onkeypress"); 2481 $button.click(function(e) { 2482 e.preventDefault(); 2483 if(!$input.prop("disabled")) $input.focus(); 2484 }); 2485 } 2486 2487 $input.data("init", true); 2488 }); 2489 2490 } 2491 2492 } 2493 } 2494} 2495 2496/*! 2497 * Este archivo lleva las acciones que se han de ejecutar para la carga de los mapas. 2498 * 2499 * Copyright(c) Divisa Informática y Telecomunicaciones S.A. 2500 */ 2501 2502var globalGmarkerImage = false;
2503var globalGmarkerShadowImage = false; 2504var globalGmarkerRouteImage = false; 2505var globalGClusterImage = false; 2506var globalGClusterShadowImage = false; 2507 2508/** 2509 * Función usada para cargar la librerÃa de Google Maps 2510 * @param {boolean} force=false Por defecto es false 2511 * @param {boolean} routingEngine=true Si habilitamos o no el motor de routing 2512 * @param {boolean} drawingEngine=false Si habilitamos o no el motor de dibujado 2513 * @param callback Función de callback 2514 * @memberOf Init 2515 */ 2516function initMaps(force, routingEngine, drawingEngine, callback) { 2517 var mapsContainer = $("div.cmMap_Container"); 2518 // Si no hay mapas no lo cargamos... 2519 if(mapsContainer.length <= 0) { 2520 if(force === undefined || force === false || force === null) return; 2521 } 2522 if(routingEngine === undefined || routingEngine === null) routingEngine = true; 2523 if(drawingEngine === undefined || drawingEngine === null) drawingEngine = false; 2524 2525 // Tenemos que cargar la configuración relacionada con el tipo de mapas. 2526 $.getJSON(_rootWeb+'/cm/gmaps/maps-configuration.json',function(mapEngineConfiguration) { 2527 // En función del motor de mapas cargamos un conjunto de scripts u otros. 2528 globalGmarkerImage = mapEngineConfiguration.markers.gmarker; 2529 globalGmarkerShadowImage = mapEngineConfiguration.markers.gmarkerShadow; 2530 globalGmarkerRouteImage = mapEngineConfiguration.markers.gmarkerRoute; 2531 globalGClusterImage = mapEngineConfiguration.markers.gcluster; 2532 globalGClusterShadowImage = mapEngineConfiguration.markers.gclusterShadow; 2533 2534 2535 switch(mapEngineConfiguration.engine) { 2536 case 'leaflet': 2537 // Cargamos los motores de CSS de leaflet, routing-machine y geocoder 2538 loadCSS(_rootWeb+'/javaScript/leaflet/core-1.9.4/leaflet.css'); 2539 loadCSS(_rootWeb+'/javaScript/leaflet/gesture-handling-1.4.4/leaflet-gesture-handling.min.css'); 2540 if(routingEngine) { 2541 loadCSS(_rootWeb+'/javaScript/leaflet/routing-machine-3.2.8/leaflet-routing-machine.css'); 2542 loadCSS(_rootWeb+'/javaScript/leaflet/control-geocoder-1.5.8/Control.Geocoder.css'); 2543 } 2544 if(drawingEngine) { 2545 loadCSS(_rootWeb+'/javaScript/leaflet/draw-0.4.14/leaflet.draw.css'); 2546 } 2547 2548 var scripts = new Array(); 2549 scripts.push(_rootWeb+'/javaScript/leaflet/core-1.9.4/leaflet.js'); 2550 scripts.push(_rootWeb+'/javaScript/leaflet/gesture-handling-1.4.4/leaflet-gesture-handling.min.js'); 2551 if(routingEngine) { 2552 // Introducimos el motor de routing correspondiente. 2553 switch(mapEngineConfiguration.leaflet.directions.provider) { 2554 case 'mapbox': 2555 scripts.push('https://api.mapbox.com/mapbox.js/v3.1.1/mapbox.js'); 2556 // La parte de routing especifica, por alguna razon debe ir antes. 2557 scripts.push(_rootWeb+'/javaScript/leaflet/routing-machine-3.2.8/leaflet-routing-machine.min.js'); 2558 scripts.push(_rootWeb+'/javaScript/leaflet/control-geocoder-1.5.8/Control.Geocoder.js'); 2559 break; 2560 case 'esri': 2561 // La parte de routing especifica. 2562 scripts.push(_rootWeb+'/javaScript/leaflet/routing-machine-3.2.8/leaflet-routing-machine.min.js'); 2563 scripts.push(_rootWeb+'/javaScript/leaflet/control-geocoder-1.5.8/Control.Geocoder.js'); 2564 // El motor de esri debe ir despues 2565 scripts.push(_rootWeb+'/javaScript/leaflet/routing-machine-esri/lrm-esri.js'); 2566 break; 2567 case 'disabled': 2568 // Solo el geocoder. 2569 scripts.push(_rootWeb+'/javaScript/leaflet/control-geocoder-1.5.8/Control.Geocoder.js'); 2570 break; 2571 default: 2572 // La parte de routing especifica. 2573 scripts.push(_rootWeb+'/javaScript/leaflet/routing-machine-3.2.8/leaflet-routing-machine.min.js'); 2574 scripts.push(_rootWeb+'/javaScript/leaflet/control-geocoder-1.5.8/Control.Geocoder.js'); 2575 break; 2576 } 2577 2578 } 2579 if(drawingEngine) { 2580 // Metemos el motro de drawing. 2581 scripts.push(_rootWeb+'/javaScript/leaflet/draw-0.4.14/leaflet.draw.js'); 2582 } 2583 2584 // Ahora lo único que tenemos que hacer es cargar todos los scripts en bloque. 2585 loadScript({url: scripts,success: function() { 2586 afterMapsLoaded(mapEngineConfiguration.leaflet,routingEngine,callback); 2587 }}); 2588 break; 2589 case 'google': 2590 // Comprobamos si hemos especificado alguna API key de Google Maps para el proyecto actual 2591 var gmapsAPIKey = mapEngineConfiguration.google.apiKey; 2592 2593 var gmapsLibrary = "https://maps.googleapis.com/ma
2593ps/api/js"; 2594 gmapsLibrary += "?language="+_userLocaleLang; 2595 gmapsLibrary += "®ion="+_userLocaleCountry; 2596 gmapsLibrary += "&libraries=drawing"; 2597 gmapsLibrary += "&callback=initGMapsLoaded"; 2598 // Chapuza... habrÃa que adaptarse a la última version en el mapsApi mandando el POI central. 2599 gmapsLibrary += "&v=3.22"; 2600 gmapsLibrary += gmapsAPIKey != null && gmapsAPIKey != "" ? "&key="+gmapsAPIKey : ""; 2601 2602 if(loadedFiles[prepareLoadedFile(gmapsLibrary)]) 2603 initGMapsLoaded(); 2604 else 2605 loadScript({ url: gmapsLibrary }); 2606 break; 2607 } 2608 }); 2609} 2610 2611/** 2612 * Función usada para pintar mapas de LeafLet 2613 * @param mapEngineConfiguration 2614 * @param routingEngine 2615 * @param callback 2616 * @memberOf Init 2617 */ 2618function afterMapsLoaded(mapEngineConfiguration,routingEngine,callback) { 2619 var mapsContainer = $("div.cmMap_Container"); 2620 2621 // La parte de atribuciones que tenemos. 2622 var attributions = new Array(); 2623 2624 // La configuración especial que tenemos asociada. 2625 var config = {mapsEngine: {}, 2626 geocodingEngine: false, 2627 directionsEngine: false, 2628 attributions: new Array()}; 2629 2630 // El motor de tiles asociado que tenemos. 2631 2632 switch(mapEngineConfiguration.maps.provider) { 2633 case 'osm': 2634 case 'bing': 2635 config.mapsEngine.url = 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png'; 2636 config.mapsEngine.options = mapEngineConfiguration.maps.options; 2637 config.attributions.push('Tiles © <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'); 2638 break; 2639 case 'mapbox': 2640 config.mapsEngine.url = 'https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token={accessToken}'; 2641 config.mapsEngine.options = $.extend($.extend({},{accessToken: mapEngineConfiguration.mapbox.apiKey}),mapEngineConfiguration.maps.options); 2642 config.attributions.push('Tiles © <a href="https://www.mapbox.com/about/maps/">Mapbox</a>, <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'); 2643 break; 2644 case 'esri': 2645 config.mapsEngine.url = 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer/tile/{z}/{y}/{x}'; 2646 config.mapsEngine.options = mapEngineConfiguration.maps.options; 2647 config.attributions.push('Tiles © Esri — Source: Esri, DeLorme, NAVTEQ, USGS, Intermap, iPC, NRCAN, Esri Japan, METI, Esri China (Hong Kong), Esri (Thailand), TomTom, 2012'); 2648 break; 2649 } 2650 2651 if(routingEngine) { 2652 // Inicalizamos el motor de geocoding asociado... 2653 switch(mapEngineConfiguration.geocoder.provider) { 2654 case 'osm': 2655 config.geocodingEngine = new L.Control.Geocoder.Nominatim(mapEngineConfiguration.geocoder.options); 2656 config.attributions.push('Geocoding © <a href="http://osm.org/copyright">OSM Nominatim</a>'); 2657 break; 2658 case 'mapbox': 2659 config.geocodingEngine = new L.Control.Geocoder.Mapbox(mapEngineConfiguration.mapbox.apiKey,mapEngineConfiguration.geocoder.options); 2660 config.attributions.push('Geocoding © <a href="https://www.mapbox.com/about/maps/">Mapbox</a>'); 2661 break; 2662 case 'bing': 2663 config.geocodingEngine = new L.Control.Geocoder.Bing(mapEngineConfiguration.bing.apiKey); 2664 config.attributions.push('Geocoding © <a href="https://www.bing.com/maps">Microsoft Bing Maps</a>'); 2665 break; 2666 case 'esri': 2667 config.geocodingEngine = new L.Control.Geocoder.ArcGis('',$.extend({service_url: mapEngineConfiguration.esri.geocoderServiceUrl},mapEngineConfiguration.geocoder.options)); 2668 config.attributions.push('Geocoding © <a href="https://www.esri.com">ESRI</a>'); 2669 break; 2670 } 2671 2672 switch(mapEngineConfiguration.directions.provider) { 2673 case 'osm': 2674 case 'bing': 2675 config.directionsEngine = new L.Routing.OSRMv1(mapEngineConfiguration.directions.options); 2676 config.attributions.push('Routing © <a href="http://project-osrm.org/">Project OSRM</a>') 2677 break; 2678 case 'esri': 2679 config.directionsEngine = new L.Routing.esri($.extend($.extend({serviceUrl: mapEngineConfiguration.esri.directionsServiceUrl}
2679,{routingOptions: {liveTraffic: false, profile: 'Driving'}}),mapEngineConfiguration.directions.options)); 2680 config.attributions.push('Routing © <a href="https://www.esri.com">ESRI</a>') 2681 break; 2682 case 'mapbox': 2683 config.directionsEngine = new L.Routing.mapbox(mapEngineConfiguration.mapbox.apiKey,mapEngineConfiguration.directions.options); 2684 config.attributions.push('Routing © <a href="https://www.mapbox.com/about/maps/">Mapbox</a>') 2685 break; 2686 } 2687 } 2688 2689 // Incializamos el motor de mapas... 2690 loadScript({ url: _rootWeb+'/javaScript/leafletMapsApi.js', success: function(){ 2691 if(callback!=undefined) { 2692 cfg = {}; 2693 cfg.routingEngine = config.directionsEngine; 2694 cfg.geocodingEngine = config.geocodingEngine; 2695 cfg.tilesEngine = config.mapsEngine 2696 cfg.attributions = config.attributions; 2697 2698 callback(cfg); 2699 } else { 2700 mapsContainer.each(function() { 2701 var gmapsThis = $(this); 2702 var gmapsMap = $("div.cmMap_googleMaps", gmapsThis); 2703 var gmapsKml = $("div.cmMap_kml", gmapsThis); 2704 if(gmapsMap.length > 0 && gmapsMap.is(":empty")) { 2705 var kmlObject = null; 2706 if(gmapsKml.length > 0) { 2707 var kmlContent = gmapsKml.html(); 2708 if(kmlContent && kmlContent != '') { 2709 kmlContent = kmlContent.replace(/<!--/g, '').replace(/-->/g, ''); 2710 kmlObject = $.parseXML(kmlContent); 2711 } 2712 } 2713 mapConfiguration = varTipoMapaUsuario; 2714 mapConfiguration.routingEngine = config.directionsEngine; 2715 mapConfiguration.geocodingEngine = config.geocodingEngine; 2716 mapConfiguration.tilesEngine = config.mapsEngine 2717 mapConfiguration.attributions = config.attributions; 2718 2719 var mapObject = new cm_LeafletMap(mapConfiguration); 2720 mapObject.cmMap_initMap(gmapsThis, kmlObject); 2721 } 2722 }); 2723 } 2724 }}); 2725} 2726 2727/** 2728 * Función usada para pintar mapas de Google Maps 2729 * @memberOf Init 2730 */ 2731function initGMapsLoaded() { 2732 loadScript({ url: _rootWeb+'/javaScript/mapsApi.js', success: function(){ 2733 var gmapsContainer = $("div.cmMap_Container"); 2734 if(gmapsContainer.length > 0) { 2735 gmapsContainer.each(function() { 2736 var gmapsThis = $(this); 2737 var gmapsMap = $("div.cmMap_googleMaps", gmapsThis); 2738 var gmapsKml = $("div.cmMap_kml", gmapsThis); 2739 if(gmapsMap.length > 0 && gmapsMap.is(":empty")) { 2740 var kmlObject = null; 2741 if(gmapsKml.length > 0) { 2742 var kmlContent = gmapsKml.html(); 2743 if(kmlContent && kmlContent != '') { 2744 kmlContent = kmlContent.replace(/<!--/g, '').replace(/-->/g, ''); 2745 kmlObject = $.parseXML(kmlContent); 2746 } 2747 } 2748 var googleMapObject = new cm_googleMap(varTipoMapaUsuario); 2749 googleMapObject.cmMap_initMap(gmapsThis, kmlObject); 2750 } 2751 }); 2752 } 2753 }}); 2754} 2755 2756//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: 2757//::: ::: 2758//::: This routine calculates the distance between two points (given the ::: 2759//::: latitude/longitude of those points). It is being used to calculate ::: 2760//::: the distance between two locations using GeoDataSource (TM) prodducts ::: 2761//::: ::: 2762//::: Definitions: ::: 2763//::: South latitudes are negative, east longitudes are positive ::: 2764//::: ::: 2765//::: Passed to function: ::: 2766//::: lat1, lon1 = Latitude and Longitude of point 1 (in decimal degrees) ::: 2767//::: lat2, lon2 = Latitude and Longitude of point 2 (in decimal degrees) ::: 2768//::: unit = the unit you desire for results ::: 2769//::: where: 'M' is statute miles (default) ::: 2770//::: 'K' is kilometers :::
2771//::: 'N' is nautical miles ::: 2772//::: ::: 2773//::: Worldwide cities and other features databases with latitude longitude ::: 2774//::: are available at https://www.geodatasource.com ::: 2775//::: ::: 2776//::: For enquiries, please contact [email protected] ::: 2777//::: ::: 2778//::: Official Web site: https://www.geodatasource.com ::: 2779//::: ::: 2780//::: GeoDataSource.com (C) All Rights Reserved 2017 ::: 2781//::: ::: 2782//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: 2783 2784/** 2785 * 2786 * @param lat1 2787 * @param lon1 2788 * @param lat2 2789 * @param lon2 2790 * @param unit 2791 * @returns {number} 2792 * @memberOf Init 2793 */ 2794function distance(lat1, lon1, lat2, lon2, unit) { 2795 var radlat1 = Math.PI * lat1/180; 2796 var radlat2 = Math.PI * lat2/180; 2797 var theta = lon1-lon2; 2798 var radtheta = Math.PI * theta/180; 2799 var dist = Math.sin(radlat1) * Math.sin(radlat2) + Math.cos(radlat1) * Math.cos(radlat2) * Math.cos(radtheta); 2800 if (dist > 1) { 2801 dist = 1; 2802 } 2803 dist = Math.acos(dist); 2804 dist = dist * 180/Math.PI; 2805 dist = dist * 60 * 1.1515; 2806 if (unit=="K") { dist = dist * 1.609344; } 2807 if (unit=="N") { dist = dist * 0.8684; } 2808 return dist; 2809} 2810 2811/** 2812 * 2813 * @param $container 2814 * @memberOf Init 2815 */ 2816function initContentListGeolocation($container) { 2817 if(!$container || $container.length == 0) return; 2818 2819 var $list = $("ul.cmContentList,ul.cmContentMultipleList", $container).first(); 2820 var $items = $("li.cmContentItem", $list); 2821 if($items.length == 0) return; 2822 2823 if (navigator.geolocation) { 2824 navigator.geolocation.getCurrentPosition(function(position) { 2825 2826 // Success: obtenemos la ubicación actual del usuario 2827 var userLat = position.coords.latitude; 2828 var userLon = position.coords.longitude; 2829 2830 var items = []; 2831 $items.each(function() { 2832 var $item = $(this); 2833 var itemLat = $("div[data-latitude]", $item).data("latitude"); 2834 var itemLon = $("div[data-longitude]", $item).data("longitude"); 2835 if(itemLat && itemLat != '' && itemLon && itemLon != '') { 2836 itemLat = parseFloat(itemLat.replace(',','.'), 10); 2837 itemLon = parseFloat(itemLon.replace(',','.'), 10); 2838 2839 // Distancia desde la ubicación del usuario a cada elemento, en metros 2840 var dist = distance(userLat, userLon, itemLat, itemLon, 'K') * 1000; 2841 2842 items.push([dist, $item]); 2843 } else { 2844 // Si el contenido no tiene coordenadas lo ponemos al final (diámetro de la tierra en metros por PI) 2845 items.push([12742 * 1000 * Math.PI, $item]); 2846 } 2847 }); 2848 2849 // Ahora ordenamos el array de items por distancia, de forma descendente, 2850 // es decir, primero el elemento más cercano al usuario 2851 items.sort(function sortFunction(a, b) { 2852 if (a[0] === b[0]) return 0; 2853 else return (a[0] < b[0]) ? -1 : 1; 2854 }); 2855 2856 // Repintamos la lista de elementos ordenados por cercanÃa 2857 $list.empty(); 2858 for(var i = 0; i < items.length; i++) { 2859 $list.append(items[i][1]); 2860 } 2861 2862 }, function() { 2863 // Error: el usuario no ha aceptado compartir su ubicación 2864 }); 2865 } 2866} 2867 2868/** 2869 * Esta función se ejecuta una vez cargado el contenido por ajaz, para incializar los scroll infinitos, rotativos, etc.. 2870 * @memberOf Init 2871 */ 2872function afterAjaxContent(){ 2873 initWayPoints(); 2874 initEndlessNavigation(); 2875 // Si existe función custom, también se ejecuta 2876 try { 2877 if (typeof(customAfterAjaxContent) == 'function'){ 2878 customAfterAjaxContent(); 2879 } 2880 } catch(ex) { 2881 } 2882 2883} 2884 2885/** 2886 * Evento load 2887 * @memberOf Init 2888 */ 2889$(window).load(function(){ 2890 2891 // Función que inicializa los mapas (Leaflet / GoogleMaps) 2892 if(typeof(wizardMode) != 'boolean' || !wizardMode) initMaps(); 2893 2894 // Función que inicializa el plugin WayPoints 2895 initWayPoints(); 2896 2897 // Función que inicializa el soporte para la autopaginacion (modo nuevo vs. waypoints que no es accesible) 2898 initEndlessNavigation(); 2899 2900 // Función que inicializa los mapas de imagen 2901 if(typeof(initImageMaps) == 'function') initImageMaps(); 2902 2903 // Función que inicializa los componentes de los blogs 2904 initBlogs(); 2905 2906 // Función que se encarga de ocultar el wait-dialog con efecto fade 2907 if(typeof(hideWaitDialog) == 'function') hideWaitDialog(true); 2908 2909});
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.