1/** 2 * @file 3 * JavaScript behaviors for Select2 integration. 4 */ 5 6(function ($, Drupal) { 7 8 'use strict'; 9 10 // @see https://select2.github.io/options.html 11 Drupal.webform = Drupal.webform || {}; 12 Drupal.webform.select2 = Drupal.webform.select2 || {}; 13 Drupal.webform.select2.options = Drupal.webform.select2.options || {}; 14 Drupal.webform.select2.options.width = Drupal.webform.select2.options.width || '100%'; 15 Drupal.webform.select2.options.widthInline = Drupal.webform.select2.options.widthInline || '50%'; 16 17 /** 18 * Initialize Select2 support. 19 * 20 * @type {Drupal~behavior} 21 */ 22 Drupal.behaviors.webformSelect2 = { 23 attach: function (context) { 24 if (!$.fn.select2) { 25 return; 26 } 27 28 $(context) 29 .find('select.js-webform-select2, .js-webform-select2 select') 30 .once('webform-select2') 31 .each(function () { 32 var $select = $(this); 33 34 var options = {}; 35 if ($select.parents('.webform-element--title-inline').length) { 36 options.width = Drupal.webform.select2.options.widthInline; 37 } 38 options = $.extend(options, Drupal.webform.select2.options); 39 if ($select.data('placeholder')) { 40 options.placeholder = $select.data('placeholder'); 41 if (!$select.prop('multiple')) { 42 // Allow single option to be deselected. 43 options.allowClear = true; 44 } 45 } 46 if ($select.data('limit')) { 47 options.maximumSelectionLength = $select.data('limit'); 48 } 49 50 // Remove required attribute from IE11 which breaks 51 // HTML5 clientside validation. 52 // @see https://github.com/select2/select2/issues/5114 53 if (window.navigator.userAgent.indexOf('Trident/') !== false 54 && $select.attr('multiple') 55 && $select.attr('required')) { 56 $select.removeAttr('required'); 57 } 58 59 $select.select2(options); 60 }); 61 62 } 63 }; 64 65 /** 66 * ISSUE: 67 * Hiding/showing element via #states API cause select2 dropdown to appear in the wrong position. 68 * 69 * WORKAROUND: 70 * Close (aka hide) select2 dropdown when #states API hides or shows an element. 71 * 72 * Steps to reproduce: 73 * - Add custom 'Submit button(s)' 74 * - Hide submit button 75 * - Save 76 * - Open 'Submit button(s)' dialog 77 * 78 * Dropdown body is positioned incorrectly when dropdownParent isn't statically positioned. 79 * @see https://github.com/select2/select2/issues/3303 80 */ 81 $(function () { 82 if ($.fn.select2) { 83 $(document).on('state:visible state:visible-slide', function (e) { 84 $('select.select2-hidden-accessible').select2('close'); 85 }); 86 } 87 88 // Select2 search broken inside jQuery UI 1.10.x modal Dialog. 89 // @see https://github.com/select2/select2/issues/1246 90 if ($.ui && $.ui.dialog && $.ui.dialog.prototype._allowInteraction) { 91 var ui_dialog_interaction = $.ui.dialog.prototype._allowInteraction; 92 $.ui.dialog.prototype._allowInteraction = function (e) { 93 if ($(e.target).closest('.select2-dropdown').length) { 94 return true; 95 } 96 return ui_dialog_interaction.apply(this, arguments); 97 }; 98 } 99 }); 100 101})(jQuery, Drupal); 102; 103/** 104 * @file 105 * JavaScript behaviors for select menu. 106 */ 107 108(function ($, Drupal) { 109 110 'use strict'; 111 112 /** 113 * Disable select menu options using JavaScript. 114 * 115 * @type {Drupal~behavior} 116 */ 117 Drupal.behaviors.webformSelectOptionsDisabled = { 118 attach: function (context) { 119 $('select[data-webform-select-options-disabled]', context).once('webform-select-options-disabled').each(function () { 120 var $select = $(this); 121 var disabled = $select.attr('data-webform-select-options-disabled').split(/\s*,\s*/); 122 $select.find('option').filter(function isDisabled() { 123 return ($.inArray(this.value, disabled) !== -1); 124 }).attr('disabled', 'disabled'); 125 }); 126 } 127 }; 128 129})(jQuery, Drupal); 130; 131/** 132* Procesa los indicadores del cintillo y los formatea horizontalmente 133*/ 134/*(function ($, Drupal) { 135 'use strict'; 136 137 138 Drupal.behaviors.indicadoresCintillo = { 139 attach: function (context, settings) { 140 // Ejecutar solo en el home 141 if (!$('body').hasClass('path-frontpage')) { 142 return; 143 } 144 145 var $cintillo = $('.cintillo-indicadores', context); 146 147 console.log('[Cintillo] Iniciando procesamiento...', $cintillo.length); 148 149 if ($cintillo.length && !$cintillo.data('processed')) { 150 $cintillo.data('processed', true); 151 console.log('[Cintillo] Cintillo encontrado, procesando...'); 152 153 // Buscar la primera lista 154 var $list1 = $cintillo.find('#indicadores-lista-1'); 155 console.log('[Cintillo] Lista 1 encontrada:', $list1.length); 156 157 if (!$list1.length) { 158 console.warn('[Cintillo] No se encontró #indicadores-lista-1'); 159 return; 160 } 161 162 // Mostrar el HTML de la lista para depuración 163 console.log('[Cintillo] Contenido HTML de lista 1:', $list1.html().substring(0, 500)); 164 165 // Buscar todos los indicadores en la estructura de la vista 166 // Estructura: .view-homepage-blocks > .view-content > .views-row > .views-field-field-indicators > .field-content > .paragraph--type--economical-indicator 167 var $indicators = $list1.find('.paragraph--type--economical-indicator'); 168 console.log('[Cintillo] Indicadores encontrados (método 1):', $indicators.length); 169 170 if ($indicators.length === 0) { 171 // Intentar buscar en diferentes niveles 172 $indicators = $list1.find('.views-field-field-indicators .paragraph--type--economical-indicator'); 173 console.log('[Cintillo] Indicadores encontrados (método 2):', $indicators.length); 174 } 175 176 // Si aún no encuentra, buscar cualquier elemento con clase paragraph 177 if ($indicators.length === 0) { 178 $indicators = $list1.find('[class*="paragraph"]'); 179 console.log('[Cintillo] Indicadores encontrados (método 3 - cualquier paragraph):', $indicators.length); 180 } 181 182 if ($indicators.length === 0) { 183 console.error('[Cintillo] No se encontraron indicadores. HTML completo:', $list1.html()); 184 return; 185 } 186 187 console.log('[Cintillo] Procesando', $indicators.length, 'indicadores...'); 188 189 // Crear lista ul vacÃa 190 var $ul = $('<ul>').addClass('indicadores-lista-items'); 191 var processedCount = 0; 192 193 // Procesar cada indicador 194 $indicators.each(function(index) { 195 var $indicator = $(this); 196 console.log('[Cintillo] Procesando indicador', index + 1, 'HTML:', $indicator.html().substring(0, 200)); 197 198 // El estado está en el contenedor padre según el template del paragraph 199 // El template muestra: <div class="{{ content.field_indicator_status.0 }}"> 200 // Entonces el estado está en el padre directo del paragraph 201 var $statusContainer = $indicator.parent(); 202 203 // Si el padre no tiene la clase, buscar en el abuelo 204 if (!$statusContainer.hasClass('sube') && !$statusContainer.hasClass('baja') && !$statusContainer.hasClass('igual')) { 205 $statusContainer = $statusContainer.parent(); 206 } 207 208 // Determinar estado 209 var status = 'igual'; 210 if ($statusContainer.length) { 211 if ($statusContainer.hasClass('sube')) { 212 status = 'sube'; 213 } else if ($statusContainer.hasClass('baja')) { 214 status = 'baja'; 215 } else if ($statusContainer.hasClass('igual')) { 216 status = 'igual'; 217 } 218 } 219 220 // También buscar dentro del paragraph por si acaso 221 var $statusInside = $indicator.find('.sube, .baja, .igual').first(); 222 if ($statusInside.length && status === 'igual') { 223 if ($statusInside.hasClass('sube')) { 224 status = 'sube'; 225 } else if ($statusInside.hasClass('baja')) { 226 status = 'baja'; 227 } 228 } 229 230 // Extraer nombre del indicador 231 // Buscar en diferentes posibles ubicaciones dentro del paragraph
232 var $name = $indicator.find('.field--name-field-indicator-name'); 233 var nameText = ''; 234 235 if ($name.length) { 236 nameText = $name.text().trim(); 237 } else { 238 // Buscar en el contenedor de estado (padre) 239 $name = $statusContainer.find('.field--name-field-indicator-name'); 240 if ($name.length) { 241 nameText = $name.text().trim(); 242 } else { 243 // Buscar cualquier elemento con clase que contenga "name" o "indicator-name" 244 $name = $indicator.find('[class*="name"]').not('[class*="status"]').first(); 245 if ($name.length) { 246 nameText = $name.text().trim(); 247 } 248 } 249 } 250 251 // Extraer valor del indicador 252 var $value = $indicator.find('.field--name-field-indicator-value'); 253 var valueText = ''; 254 255 if ($value.length) { 256 valueText = $value.text().trim(); 257 } else { 258 // Buscar en el contenedor de estado (padre) 259 $value = $statusContainer.find('.field--name-field-indicator-value'); 260 if ($value.length) { 261 valueText = $value.text().trim(); 262 } else { 263 // Buscar cualquier elemento con clase que contenga "value" 264 $value = $indicator.find('[class*="value"]').not('[class*="status"]').first(); 265 if ($value.length) { 266 valueText = $value.text().trim(); 267 } 268 } 269 } 270 271 // Si no hay nombre o valor, saltar este indicador 272 if (!nameText || !valueText) { 273 console.warn('[Cintillo] Indicador', index + 1, 'sin nombre o valor. Nombre:', nameText, 'Valor:', valueText); 274 return; 275 } 276 277 console.log('[Cintillo] Indicador', index + 1, 'procesado - Nombre:', nameText, 'Valor:', valueText, 'Estado:', status); 278 279 // Crear elemento li 280 var $li = $('<li>'); 281 $li.append($('<span>').addClass('texto-indicador').text(nameText)); 282 $li.append($('<span>').text(valueText)); 283 processedCount++; 284 285 // Buscar cambio/variación si existe 286 var $change = $indicator.find('.field--name-field-indicator-change, .field--name-field-indicator-variation'); 287 if (!$change.length && $statusContainer.length) { 288 $change = $statusContainer.find('.field--name-field-indicator-change, .field--name-field-indicator-variation'); 289 } 290 291 var changeText = $change.length ? $change.text().trim() : ''; 292 293 // Agregar cambio si existe y tiene estado 294 if (changeText && status !== 'igual') { 295 $li.append($('<span>').addClass(status).text(changeText)); 296 } 297 298 $ul.append($li); 299 }); 300 301 // Si no se encontraron indicadores, salir 302 if ($ul.children().length === 0) { 303 console.error('[Cintillo] No se procesaron indicadores. Total encontrados:', $indicators.length, 'Procesados:', processedCount); 304 return; 305 } 306 307 308 console.log('[Cintillo] Total indicadores procesados:', processedCount, 'de', $indicators.length); 309 310 311 // Reemplazar todo el contenido de la primera lista 312 $list1.empty().append($ul); 313 $list1.addClass('processed'); 314 console.log('[Cintillo] Lista 1 actualizada con', $ul.children().length, 'elementos'); 315 316 // Ocultar todos los paragraphs originales después de procesarlos 317 $list1.find('.paragraph--type--economical-indicator, .field-content').hide(); 318 319 // Marcar el cintillo como procesado 320 $cintillo.addClass('processed'); 321 322 // Duplicar contenido para efecto infinito en la segunda lista 323 var $list2 = $cintillo.find('#indicadores-lista-2'); 324 if ($list2.length && $ul.children().length > 0) { 325 // Clonar la lista completa (ul con todos sus li) 326 var $ulClone = $ul.clone(); 327 $list2.empty().append($ulClone); 328 $list2.addClass('processed'); 329 } 330 331 // Ajustar velocidad de animación según cantidad de indicadores 332 var $container = $cintillo.find('.indicadores__cifras-container'); 333 var totalWidth = $ul[0] ? $ul[0].scrollWidth : 0; 334 console.log('[Cintillo] Ancho total:', totalWidth); 335 if (totalWidth > 0) { 336 var speed = totalWidth / 50; // 50px por segundo 337 $container.css('animation-duration', speed + 's'); 338 console.log('[Cintillo] Velocidad de animación ajustada a', speed, 'segundos'); 339 } 340 341 console.log('[Cintillo] Procesamiento completado exitosamente'); 342 } else { 343 if ($cintillo.length) { 344 console.log('[Cintillo] Cintillo ya procesado anteriormente'); 345 } else { 346 console.warn('[Cintillo] No se encontró el elemento .cintillo-indicadores'); 347 } 348 } 349 } 350 }; 351})(jQuery, Drupal);*/; 352/* 353 * Superfish v1.4.8 - jQuery menu widget 354 * Copyright (c) 2008 Joel Birch 355 * 356 * Dual licensed under the MIT and GPL licenses: 357 * http://www.opensource.org/licenses/mit-license.php 358 * http://www.gnu.org/licenses/gpl.html 359 * 360 * CHANGELOG: http://users.tpg.com.au/j_birch/plugins/superfish/changelog.txt 361 */ 362/* 363 * This is not the original jQuery Superfish plugin. 364 * Please refer to the README for more information. 365 */ 366 367(function($){ 368 $.fn.superfish = function(op){ 369 var sf = $.fn.superfish, 370 c = sf.c, 371 $arrow = $(['<span class="',c.arrowClass,'"> »</span>'].join('')), 372 over = function(){ 373 var $$ = $(this), menu = getMenu($$); 374 clearTimeout(menu.sfTimer); 375 $$.showSuperfishUl().siblings().hideSuperfishUl(); 376 }, 377 out = function(){ 378 var $$ = $(this), menu = getMenu($$), o = sf.op; 379 clearTimeout(menu.sfTimer); 380 menu.sfTimer=setTimeout(function(){ 381 if ($$.children('.sf-clicked').length == 0){ 382 o.retainPath=($.inArray($$[0],o.$path)>-1);
383 $$.hideSuperfishUl(); 384 if (o.$path.length && $$.parents(['li.',o.hoverClass].join('')).length<1){over.call(o.$path);} 385 } 386 },o.delay); 387 }, 388 getMenu = function($menu){ 389 var menu = $menu.parents(['ul.',c.menuClass,':first'].join(''))[0]; 390 sf.op = sf.o[menu.serial]; 391 return menu; 392 }, 393 addArrow = function($a){ $a.addClass(c.anchorClass).append($arrow.clone()); }; 394 395 return this.each(function() { 396 var s = this.serial = sf.o.length; 397 var o = $.extend({},sf.defaults,op); 398 o.$path = $('li.'+o.pathClass,this).slice(0,o.pathLevels), 399 p = o.$path; 400 for (var l = 0; l < p.length; l++){ 401 p.eq(l).addClass([o.hoverClass,c.bcClass].join(' ')).filter('li:has(ul)').removeClass(o.pathClass); 402 } 403 sf.o[s] = sf.op = o; 404 405 $('li:has(ul)',this)[($.fn.hoverIntent && !o.disableHI) ? 'hoverIntent' : 'hover'](over,out).each(function() { 406 if (o.autoArrows) addArrow( $(this).children('a:first-child, span.nolink:first-child') ); 407 }) 408 .not('.'+c.bcClass) 409 .hideSuperfishUl(); 410 411 var $a = $('a, span.nolink',this); 412 $a.each(function(i){ 413 var $li = $a.eq(i).parents('li'); 414 $a.eq(i).focus(function(){over.call($li);}).blur(function(){out.call($li);}); 415 }); 416 o.onInit.call(this); 417 418 }).each(function() { 419 var menuClasses = [c.menuClass]; 420 if (sf.op.dropShadows){ 421 menuClasses.push(c.shadowClass); 422 } 423 $(this).addClass(menuClasses.join(' ')); 424 }); 425 }; 426 427 var sf = $.fn.superfish; 428 sf.o = []; 429 sf.op = {}; 430 431 sf.c = { 432 bcClass: 'sf-breadcrumb', 433 menuClass: 'sf-js-enabled', 434 anchorClass: 'sf-with-ul', 435 arrowClass: 'sf-sub-indicator', 436 shadowClass: 'sf-shadow' 437 }; 438 sf.defaults = { 439 hoverClass: 'sfHover', 440 pathClass: 'overideThisToUse', 441 pathLevels: 1, 442 delay: 800, 443 animation: {opacity:'show'}, 444 speed: 'fast', 445 autoArrows: true, 446 dropShadows: true, 447 disableHI: false, // true disables hoverIntent detection 448 onInit: function(){}, // callback functions 449 onBeforeShow: function(){}, 450 onShow: function(){}, 451 onHide: function(){} 452 }; 453 $.fn.extend({ 454 hideSuperfishUl : function(){ 455 var o = sf.op, 456 not = (o.retainPath===true) ? o.$path : ''; 457 o.retainPath = false; 458 var $ul = $(['li.',o.hoverClass].join(''),this).add(this).not(not).removeClass(o.hoverClass) 459 .children('ul').addClass('sf-hidden'); 460 o.onHide.call($ul); 461 return this; 462 }, 463 showSuperfishUl : function(){ 464 var o = sf.op, 465 sh = sf.c.shadowClass+'-off', 466 $ul = this.addClass(o.hoverClass) 467 .children('ul.sf-hidden').hide().removeClass('sf-hidden'); 468 o.onBeforeShow.call($ul); 469 $ul.animate(o.animation,o.speed,function(){ o.onShow.call($ul); }); 470 return this; 471 } 472 }); 473})(jQuery);; 474/*! 475 * hoverIntent v1.8.0 // 2014.06.29 // jQuery v1.9.1+ 476 * http://cherne.net/brian/resources/jquery.hoverIntent.html 477 * 478 * You may use hoverIntent under the terms of the MIT license. Basically that 479 * means you are free to use hoverIntent as long as this header is left intact. 480 * Copyright 2007, 2014 Brian Cherne 481 */ 482(function($){$.fn.hoverIntent=function(handlerIn,handlerOut,selector){var cfg={interval:100,sensitivity:6,timeout:0};if(typeof handlerIn==="object"){cfg=$.extend(cfg,handlerIn)}else{if($.isFunction(handlerOut)){cfg=$.extend(cfg,{over:handlerIn,out:handlerOut,selector:selector})}else{cfg=$.extend(cfg,{over:handlerIn,out:handlerIn,selector:handlerOut})}}var cX,cY,pX,pY;var track=function(ev){cX=ev.pageX;cY=ev.pageY};var compare=function(ev,ob){ob.hoverIntent_t=clearTimeout(ob.hoverIntent_t);if(Math.sqrt((pX-cX)*(pX-cX)+(pY-cY)*(pY-cY))<cfg.sensitivity){$(ob).off("mousemove.hoverIntent",track);ob.hoverIntent_s=true;return cfg.over.apply(ob,[ev])}else{pX=cX;pY=cY;ob.hoverIntent_t=setTimeout(function(){compare(ev,ob)},cfg.interval)}};var delay=function(ev,ob){ob.hoverIntent_t=clearTimeout(ob.hoverIntent_t);ob.hoverIntent_s=false;return cfg.out.apply(ob,[ev])};var handleHover=function(e){var ev=$.extend({},e);var ob=this;if(ob.hoverIntent_t){ob.hoverIntent_t=clearTimeout(ob.hoverIntent_t)}if(e.type==="mouseenter"){pX=ev.pageX;pY=ev.pageY;$(ob).on("mousemove.hoverIntent",track);if(!ob.hoverIntent_s){ob.hoverIntent_t=setTimeout(function(){compare(ev,ob)},cfg.interval)}}else{$(ob).off("mousemove.hoverIntent",track);if(ob.hoverIntent_s){ob.hoverIntent_t=setTimeout(function(){delay(ev,ob)},cfg.timeout)}}};return this.on({"mouseenter.hoverIntent":handleHover,"mouseleave.hoverIntent":handleHover},cfg.selector)}})(jQuery);; 483/* 484 * sf-Smallscreen v1.3b - Provides small-screen compatibility for the jQuery Superfish plugin. 485 * 486 * Developer's note: 487 * Built as a part of the Superfish project for Drupal (http://drupal.org/project/superfish) 488 * Found any bug? have any cool ideas? contact me right away! http://drupal.org/user/619294/contact 489 * 490 * jQuery version: 1.3.x or higher. 491 * 492 * Dual licensed under the MIT and GPL licenses: 493 * http://www.opensource.org/licenses/mit-license.php 494 * http://www.gnu.org/licenses/gpl.html 495 */ 496 497(function($){ 498 $.fn.sfsmallscreen = function(options){ 499 options = $.extend({ 500 mode: 'inactive', 501 type: 'accordion', 502 breakpoint: 768, 503 breakpointUnit: 'px', 504 useragent: '', 505 title: '', 506 addSelected: false, 507 menuClasses: false, 508 hyperlinkClasses: false, 509 excludeClass_menu: '', 510 excludeClass_hyperlink: '', 511 includeClass_menu: '', 512 includeClass_hyperlink: '', 513 accordionButton: 1, 514 expandText: 'Expand', 515 collapseText: 'Collapse' 516 }, options); 517 518 // We need to clean up the menu from anything unnecessary. 519 function refine(menu){ 520 var
521 refined = menu.clone(), 522 // Things that should not be in the small-screen menus. 523 rm = refined.find('span.sf-sub-indicator'), 524 // This is a helper class for those who need to add extra markup that shouldn't exist 525 // in the small-screen versions. 526 rh = refined.find('.sf-smallscreen-remove'), 527 // Mega-menus has to be removed too. 528 mm = refined.find('ul.sf-multicolumn'); 529 for (var a = 0; a < rh.length; a++){ 530 rh.eq(a).replaceWith(rh.eq(a).html()); 531 } 532 if (options.accordionButton == 2 || options.type == 'select'){ 533 for (var b = 0; b < rm.length; b++){ 534 rm.eq(b).remove(); 535 } 536 } 537 if (mm.length > 0){ 538 mm.removeClass('sf-multicolumn'); 539 var ol = refined.find('div.sf-multicolumn-column > ol'); 540 for (var o = 0; o < ol.length; o++){ 541 ol.eq(o).replaceWith('<ul>' + ol.eq(o).html() + '</ul>'); 542 } 543 var elements = ['div.sf-multicolumn-column','.sf-multicolumn-wrapper > ol','li.sf-multicolumn-wrapper']; 544 for (var i = 0; i < elements.length; i++){ 545 obj = refined.find(elements[i]); 546 for (var t = 0; t < obj.length; t++){ 547 obj.eq(t).replaceWith(obj.eq(t).html()); 548 } 549 } 550 refined.find('.sf-multicolumn-column').removeClass('sf-multicolumn-column'); 551 } 552 refined.add(refined.find('*')).css({width:''}); 553 return refined; 554 } 555 556 // Creating <option> elements out of the menu. 557 function toSelect(menu, level){ 558 var 559 items = '', 560 childLI = $(menu).children('li'); 561 for (var a = 0; a < childLI.length; a++){ 562 var list = childLI.eq(a), parent = list.children('a, span'); 563 for (var b = 0; b < parent.length; b++){ 564 var 565 item = parent.eq(b), 566 path = (item.is('a') && !!item.attr('href')) ? item.attr('href') : '', 567 // Class names modification. 568 itemClone = item.clone(), 569 classes = (options.hyperlinkClasses) ? ((options.excludeClass_hyperlink && itemClone.hasClass(options.excludeClass_hyperlink)) ? itemClone.removeClass(options.excludeClass_hyperlink).attr('class') : itemClone.attr('class')) : '', 570 classes = (options.includeClass_hyperlink && !itemClone.hasClass(options.includeClass_hyperlink)) ? ((options.hyperlinkClasses) ? itemClone.addClass(options.includeClass_hyperlink).attr('class') : options.includeClass_hyperlink) : classes; 571 // Retaining the active class if requested. 572 if (options.addSelected && item.hasClass('active')){ 573 classes += ' active'; 574 } 575 classes = (classes) ? ' class="' + classes + '"' : ''; 576 // <option> has to be disabled if the item is not a link. 577 disable = (path == '') || (path == '#') ? ' disabled="disabled"' : '', 578 // Crystal clear. 579 subIndicator = 1 < level ? Array(level).join('-') + ' ' : ''; 580 // Preparing the <option> element. 581 items += '<option value="' + path + '"' + classes + disable + '>' + subIndicator + $.trim(item.text()) +'</option>', 582 childUL = list.find('> ul'); 583 // Using the function for the sub-menu of this item. 584 for (var u = 0; u < childUL.length; u++){ 585 items += toSelect(childUL.eq(u), level + 1); 586 } 587 } 588 } 589 return items; 590 } 591 592 // Create the new version, hide the original. 593 function convert(menu){ 594 var menuID = menu.attr('id'), 595 // Creating a refined version of the menu. 596 refinedMenu = refine(menu); 597 // Currently the plugin provides two reactions to small screens. 598 // Converting the menu to a <select>
598 element, and converting to an accordion version of the menu. 599 if (options.type == 'accordion'){ 600 var 601 toggleID = menuID + '-toggle', 602 accordionID = menuID + '-accordion'; 603 // Making sure the accordion does not exist. 604 if ($('#' + accordionID).length == 0){ 605 var 606 // Getting the style class. 607 styleClass = menu.attr('class').split(' ').filter(function(item){ 608 return item.indexOf('sf-style-') > -1 ? item : ''; 609 }), 610 // Creating the accordion. 611 accordion = $(refinedMenu).attr('id', accordionID); 612 // Removing unnecessary classes. 613 accordion.removeClass('sf-horizontal sf-vertical sf-navbar sf-shadow sf-js-enabled'); 614 // Adding necessary classes. 615 accordion.addClass('sf-accordion sf-hidden'); 616 // Removing style attributes and any unnecessary class. 617 accordion.find('li').each(function(){ 618 $(this).removeAttr('style').removeClass('sfHover').attr('id', $(this).attr('id') + '-accordion'); 619 }); 620 // Doing the same and making sure all the sub-menus are off-screen (hidden). 621 accordion.children('ul').removeAttr('style').not('.sf-hidden').addClass('sf-hidden'); 622 // Creating the accordion toggle switch. 623 var toggle = '<div class="sf-accordion-toggle ' + styleClass + '"><a href="#" id="' + toggleID + '"><span>' + options.title + '</span></a></div>'; 624 625 // Adding Expand\Collapse buttons if requested. 626 if (options.accordionButton == 2){ 627 accordion.addClass('sf-accordion-with-buttons'); 628 var parent = accordion.find('li.menuparent'); 629 for (var i = 0; i < parent.length; i++){ 630 parent.eq(i).prepend('<a href="#" class="sf-accordion-button">' + options.expandText + '</a>'); 631 } 632 } 633 // Inserting the according and hiding the original menu. 634 menu.before(toggle).before(accordion).hide(); 635 636 var 637 accordionElement = $('#' + accordionID), 638 // Deciding what should be used as accordion buttons. 639 buttonElement = (options.accordionButton < 2) ? 'a.menuparent,span.nolink.menuparent' : 'a.sf-accordion-button', 640 button = accordionElement.find(buttonElement); 641 642 // Attaching a click event to the toggle switch. 643 $('#' + toggleID).on('click', function(e){ 644 // Preventing the click. 645 e.preventDefault(); 646 // Adding the sf-expanded class. 647 $(this).toggleClass('sf-expanded'); 648 649 if (accordionElement.hasClass('sf-expanded')){ 650 // If the accordion is already expanded: 651 // Hiding its expanded sub-menus and then the accordion itself as well. 652 accordionElement.add(accordionElement.find('li.sf-expanded')).removeClass('sf-expanded') 653 .end().children('ul').hide() 654 // This is a bit tricky, it's the same trick that has been in use in the main plugin for some time. 655 // Basically we'll add a class that keeps the sub-menu off-screen and still visible, 656 // and make it invisible and removing the class one moment before showing or hiding it. 657 // This helps screen reader software access all the menu items. 658 .end().hide().addClass('sf-hidden').show(); 659 // Changing the caption of any existing accordion buttons to 'Expand'. 660 if (options.accordionButton == 2){ 661 accordionElement.find('a.sf-accordion-button').text(options.expandText); 662 } 663 } 664 else { 665 // But if it's collapsed, 666 accordionElement.addClass('sf-expanded').hide().removeClass('sf-hidden').show(); 667 } 668 }); 669 670 // Attaching a click event to the buttons. 671 button.on('click', function(e){ 672 // Making sure the buttons does not exist already. 673 if ($(this).closest('li').children('ul').length > 0){ 674 e.preventDefault(); 675 // Selecting the parent menu items. 676 var parent = $(this).closest('li'); 677 // Creating and inserting Expand\Collapse buttons to the parent menu items, 678 // of course only if not already happened.
679 if (options.accordionButton == 1 && parent.children('a.menuparent,span.nolink.menuparent').length > 0 && parent.children('ul').children('li.sf-clone-parent').length == 0){ 680 var 681 // Cloning the hyperlink of the parent menu item. 682 cloneLink = parent.children('a.menuparent,span.nolink.menuparent').clone(); 683 // Removing unnecessary classes and element(s). 684 cloneLink.removeClass('menuparent sf-with-ul').children('.sf-sub-indicator').remove(); 685 // Wrapping the hyerplinks in <li>. 686 cloneLink = $('<li class="sf-clone-parent" />').html(cloneLink); 687 // Adding a helper class and attaching them to the sub-menus. 688 parent.children('ul').addClass('sf-has-clone-parent').prepend(cloneLink); 689 } 690 // Once the button is clicked, collapse the sub-menu if it's expanded. 691 if (parent.hasClass('sf-expanded')){ 692 parent.children('ul').slideUp('fast', function(){ 693 // Doing the accessibility trick after hiding the sub-menu. 694 $(this).closest('li').removeClass('sf-expanded').end().addClass('sf-hidden').show(); 695 }); 696 // Changing the caption of the inserted Collapse link to 'Expand', if any is inserted. 697 if (options.accordionButton == 2 && parent.children('.sf-accordion-button').length > 0){ 698 parent.children('.sf-accordion-button').text(options.expandText); 699 } 700 } 701 // Otherwise, expand the sub-menu. 702 else { 703 // Doing the accessibility trick and then showing the sub-menu. 704 parent.children('ul').hide().removeClass('sf-hidden').slideDown('fast') 705 // Changing the caption of the inserted Expand link to 'Collape', if any is inserted. 706 .end().addClass('sf-expanded').children('a.sf-accordion-button').text(options.collapseText) 707 // Hiding any expanded sub-menu of the same level. 708 .end().siblings('li.sf-expanded').children('ul') 709 .slideUp('fast', function(){ 710 // Doing the accessibility trick after hiding it. 711 $(this).closest('li').removeClass('sf-expanded').end().addClass('sf-hidden').show(); 712 }) 713 // Assuming Expand\Collapse buttons do exist, resetting captions, in those hidden sub-menus. 714 .parent().children('a.sf-accordion-button').text(options.expandText); 715 } 716 } 717 }); 718 } 719 } 720 else { 721 var 722 // Class names modification. 723 menuClone = menu.clone(), classes = (options.menuClasses) ? ((options.excludeClass_menu && menuClone.hasClass(options.excludeClass_menu)) ? menuClone.removeClass(options.excludeClass_menu).attr('class') : menuClone.attr('class')) : '', 724 classes = (options.includeClass_menu && !menuClone.hasClass(options.includeClass_menu)) ? ((options.menuClasses) ? menuClone.addClass(options.includeClass_menu).attr('class') : options.includeClass_menu) : classes, 725 classes = (classes) ? ' class="' + classes + '"' : ''; 726 727 // Making sure the <select> element does not exist already. 728 if ($('#' + menuID + '-select').length == 0){ 729 // Creating the <option> elements. 730 var newMenu = toSelect(refinedMenu, 1), 731 // Creating the <select> element and assigning an ID and class name. 732 selectList = $('<select' + classes + ' id="' + menuID + '-select"/>') 733 // Attaching the title and the items to the <select> element. 734 .html('<option>' + options.title + '</option>' + newMenu) 735 // Attaching an event then. 736 .change(function(){ 737 // Except for the first option that is the menu title and not a real menu item. 738 if ($('option:selected', this).index()){ 739 window.location = selectList.val(); 740 } 741 }); 742 // Applying the addSelected option to it. 743 if (options.addSelected){ 744 selectList.find('.active').attr('selected', !0); 745 } 746 // Finally inserting the <select> element into the document then hiding the original menu. 747 menu.before(selectList).hide(); 748 } 749 } 750 } 751 752 // Turn everything back to normal. 753 function turnBack(menu){ 754 var 755 id = '#' + menu.attr('id'); 756 // Removing the small screen version. 757 $(id + '-' + options.type).remove(); 758 // Removing the accordion toggle switch as well. 759 if (options.type == 'accordion'){ 760 $(id + '-toggle').parent('div').remove(); 761 } 762 // Remove inline CSS display property; less clear than simply using .show(), but respects stylesheet 763 $(id).css('display', ''); 764 } 765
766 // Return original object to support chaining. 767 // Although this is unnecessary because of the way the module uses these plugins. 768 for (var s = 0; s < this.length; s++){ 769 var 770 menu = $(this).eq(s), 771 mode = options.mode; 772 // The rest is crystal clear, isn't it? :) 773 if (mode == 'always_active'){ 774 convert(menu); 775 } 776 else if (mode == 'window_width'){ 777 var breakpoint = (options.breakpointUnit == 'em') ? (options.breakpoint * parseFloat($('body').css('font-size'))) : options.breakpoint, 778 windowWidth = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth, 779 timer; 780 if ((typeof Modernizr === 'undefined' || typeof Modernizr.mq !== 'function') && windowWidth < breakpoint){ 781 convert(menu); 782 } 783 else if (typeof Modernizr !== 'undefined' && typeof Modernizr.mq === 'function' && Modernizr.mq('(max-width:' + (breakpoint - 1) + 'px)')) { 784 convert(menu); 785 } 786 $(window).resize(function(){ 787 clearTimeout(timer); 788 timer = setTimeout(function(){ 789 var windowWidth = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth; 790 if ((typeof Modernizr === 'undefined' || typeof Modernizr.mq !== 'function') && windowWidth < breakpoint){ 791 convert(menu); 792 } 793 else if (typeof Modernizr !== 'undefined' && typeof Modernizr.mq === 'function' && Modernizr.mq('(max-width:' + (breakpoint - 1) + 'px)')) { 794 convert(menu); 795 } 796 else { 797 turnBack(menu); 798 } 799 }, 50); 800 }); 801 } 802 else if (mode == 'useragent_custom'){ 803 if (options.useragent != ''){ 804 var ua = RegExp(options.useragent, 'i'); 805 if (navigator.userAgent.match(ua)){ 806 convert(menu); 807 } 808 } 809 } 810 else if (mode == 'useragent_predefined' && navigator.userAgent.match(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od|ad)|iris|kindle|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i)){ 811 convert(menu); 812 } 813 } 814 return this; 815 } 816})(jQuery); 817; 818/* 819 * Supposition v0.2 - an optional enhancer for Superfish jQuery menu widget. 820 * 821 * Copyright (c) 2008 Joel Birch - based mostly on work by Jesse Klaasse and credit goes largely to him. 822 * Special thanks to Karl Swedberg for valuable input. 823 * 824 * Dual licensed under the MIT and GPL licenses: 825 * http://www.opensource.org/licenses/mit-license.php 826 * http://www.gnu.org/licenses/gpl.html 827 */ 828/* 829 * This is not the original jQuery Supposition plugin. 830 * Please refer to the README for more information. 831 */ 832 833(function($){ 834 $.fn.supposition = function(){ 835 var $w = $(window), /*do this once instead of every onBeforeShow call*/ 836 _offset = function(dir) { 837 return window[dir == 'y' ? 'pageYOffset' : 'pageXOffset'] 838 || document.documentElement && document.documentElement[dir=='y' ? 'scrollTop' : 'scrollLeft'] 839 || document.body[dir=='y' ? 'scrollTop' : 'scrollLeft']; 840 }, 841 onHide = function(){ 842 this.css({bottom:''}); 843 }, 844 onBeforeShow = function(){ 845 this.each(function(){ 846 var $u = $(this); 847 $u.css('display','block'); 848 var $mul = $u.closest('.sf-menu'), 849 level = $u.parents('ul').length, 850 menuWidth = $u.width(), 851 menuParentWidth = $u.closest('li').outerWidth(true), 852 menuParentLeft = $u.closest('li').offset().left, 853 totalRight = $w.width() + _offset('x'), 854 menuRight = $u.offset().left + menuWidth, 855 exactMenuWidth = (menuRight > (menuParentWidth + menuParentLeft)) ? menuWidth - (menuRight - (menuParentWidth + menuParentLeft)) : menuWidth; 856 if ($u.parents('.sf-js-enabled').hasClass('rtl')) { 857 if (menuParentLeft < exactMenuWidth) { 858 if (($mul.hasClass('sf-horizontal') && level == 1) || ($mul.hasClass('sf-navbar') && level == 2)){ 859 $u.css({left:0,right:'auto'}); 860 } 861 else { 862 $u.css({left:menuParentWidth + 'px',right:'auto'}); 863 } 864 } 865 } 866 else { 867 if (menuRight > totalRight && menuParentLeft > menuWidth) { 868 if (($mul.hasClass('sf-horizontal') && level == 1) || ($mul.hasClass('sf-navbar') && level == 2)){ 869 $u.css({right:0,left:'auto'}); 870 } 871 else { 872 $u.css({right:menuParentWidth + 'px',left:'auto'}); 873 } 874 } 875 } 876 var windowHeight = $w.height(), 877 offsetTop = $u.offset().top, 878 menuParentShadow = ($mul.hasClass('sf-shadow') && $u.css('padding-bottom').length > 0) ? parseInt($u.css('padding-bottom').slice(0,-2)) : 0, 879 menuParentHeight = ($mul.hasClass('sf-vertical')) ? '-' + menuParentShadow : $u.parent().outerHeight(true) - menuParentShadow, 880 menuHeight = $u.height(), 881 baseline = windowHeight + _offset('y'); 882 var expandUp = ((offsetTop + menuHeight > baseline) && (offsetTop > menuHeight)); 883 if (expandUp) { 884 $u.css({bottom:menuParentHeight + 'px',top:'auto'}); 885 } 886 $u.css('display','none'); 887 }); 888 }; 889 890 return this.each(function() { 891 var o = $.fn.superfish.o[this.serial]; /* get this menu's options */ 892 893 /* if callbacks already set, store them */ 894 var _onBeforeShow = o.onBeforeShow, 895 _onHide = o.onHide; 896 897 $.extend($.fn.superfish.o[this.serial],{ 898 onBeforeShow: function() { 899 onBeforeShow.call(this); /* fire our Supposition callback */ 900 _onBeforeShow.call(this); /* fire stored callbacks */ 901 }, 902 onHide: function() { 903 onHide.call(this); /* fire our Supposition callback */ 904 _onHide.call(this); /* fire stored callbacks */ 905 } 906 }); 907 }); 908 }; 909})(jQuery);; 910/* 911 * Supersubs v0.4b - jQuery plugin 912 * Copyright (c) 2013 Joel Birch 913 * 914 * Dual licensed under the MIT and GPL licenses: 915 * http://www.opensource.org/licenses/mit-license.php 916 * http://www.gnu.org/licenses/gpl.html 917 * 918 * This plugin automatically adjusts submenu widths of suckerfish-style menus to that of 919 * their longest list item children. If you use this, please expect bugs and report them 920 * to the jQuery Google Group with the word 'Superfish' in the subject line. 921 * 922 */ 923/* 924 * This is not the original jQuery Supersubs plugin. 925 * Please refer to the README for more information. 926 */ 927 928(function($){ // $ will refer to jQuery within this closure 929 $.fn.supersubs = function(options){ 930 var opts = $.extend({}, $.fn.supersubs.defaults, options);
931 // return original object to support chaining 932 // Although this is unnecessary due to the way the module uses these plugins. 933 for (var a = 0; a < this.length; a++) { 934 // cache selections 935 var $$ = $(this).eq(a), 936 // support metadata 937 o = $.meta ? $.extend({}, opts, $$.data()) : opts; 938 // Jump one level if it's a "NavBar" 939 if ($$.hasClass('sf-navbar')) { 940 $$ = $$.children('li').children('ul'); 941 } 942 // cache all ul elements 943 var $ULs = $$.find('ul'), 944 // get the font size of menu. 945 // .css('fontSize') returns various results cross-browser, so measure an em dash instead 946 fontsize = $('<li id="menu-fontsize">—</li>'), 947 size = fontsize.attr('style','padding:0;position:absolute;top:-99999em;width:auto;') 948 .appendTo($$)[0].clientWidth; //clientWidth is faster than width() 949 // remove em dash 950 fontsize.remove(); 951 952 // loop through each ul in menu 953 for (var b = 0; b < $ULs.length; b++) { 954 var 955 // cache this ul 956 $ul = $ULs.eq(b); 957 // If a multi-column sub-menu, and only if correctly configured. 958 if (o.multicolumn && $ul.hasClass('sf-multicolumn') && $ul.find('.sf-multicolumn-column').length > 0){ 959 // Look through each column. 960 var $column = $ul.find('div.sf-multicolumn-column > ol'), 961 // Overall width. 962 mwWidth = 0; 963 for (var d = 0; d < $column.length; d++){ 964 resize($column.eq(d)); 965 // New column width, in pixels. 966 var colWidth = $column.width(); 967 // Just a trick to convert em unit to px. 968 $column.css({width:colWidth}) 969 // Making column parents the same size. 970 .parents('.sf-multicolumn-column').css({width:colWidth}); 971 // Overall width. 972 mwWidth += parseInt(colWidth); 973 } 974 // Resizing the columns container too. 975 $ul.add($ul.find('li.sf-multicolumn-wrapper, li.sf-multicolumn-wrapper > ol')).css({width:mwWidth}); 976 } 977 else { 978 resize($ul); 979 } 980 } 981 } 982 function resize($ul){ 983 var 984 // get all (li) children of this ul 985 $LIs = $ul.children(), 986 // get all anchor grand-children 987 $As = $LIs.children('a'); 988 // force content to one line and save current float property 989 $LIs.css('white-space','nowrap'); 990 // remove width restrictions and floats so elements remain vertically stacked 991 $ul.add($LIs).add($As).css({float:'none',width:'auto'}); 992 // this ul will now be shrink-wrapped to longest li due to position:absolute 993 // so save its width as ems. 994 var emWidth = $ul.get(0).clientWidth / size; 995 // add more width to ensure lines don't turn over at certain sizes in various browsers 996 emWidth += o.extraWidth; 997 // restrict to at least minWidth and at most maxWidth 998 if (emWidth > o.maxWidth) {emWidth = o.maxWidth;} 999 else if (emWidth < o.minWidth) {emWidth = o.minWidth;} 1000 emWidth += 'em'; 1001 // set ul to width in ems 1002 $ul.css({width:emWidth}); 1003 // restore li floats to avoid IE bugs 1004 // set li width to full width of this ul 1005 // revert white-space to normal 1006 $LIs.add($As).css({float:'',width:'',whiteSpace:''}); 1007 // update offset position of descendant ul to reflect new width of parent. 1008 // set it to 100% in case it isn't already set to this in the CSS 1009 for (var c = 0; c < $LIs.length; c++) { 1010 var $childUl = $LIs.eq(c).children('ul'); 1011 var offsetDirection = $childUl.css('left') !== undefined ? 'left' : 'right'; 1012 $childUl.css(offsetDirection,'100%'); 1013 } 1014 } 1015 return this; 1016 }; 1017 // expose defaults 1018 $.fn.supersubs.defaults = { 1019 multicolumn: true, // define width for multi-column sub-menus and their columns. 1020 minWidth: 12, // requires em unit. 1021 maxWidth: 27, // requires em unit. 1022 extraWidth: 1 // extra width can ensure lines don't sometimes turn over due to slight browser differences in how they round-off values 1023 }; 1024})(jQuery); // plugin code ends 1025; 1026/** 1027 * @file 1028 * The Superfish Drupal Behavior to apply the Superfish jQuery plugin to lists. 1029 */ 1030 1031(function ($, Drupal, drupalSettings) { 1032 1033 'use strict'; 1034 1035 /** 1036 * jQuery Superfish plugin. 1037 * 1038 * @type {Drupal~behavior} 1039 * 1040 * @prop {Drupal~behaviorAttach} attach 1041 * Attaches the behavior to an applicable <ul> element. 1042 */ 1043 Drupal.behaviors.superfish = { 1044 attach: function (context, drupalSettings) { 1045 // Take a look at each menu to apply Superfish to. 1046 $.each(drupalSettings.superfish || {}, function (index, options) { 1047 var $menu = $('ul#' + options.id, context); 1048 1049 // Check if we are to apply the Supersubs plug-in to it. 1050 if (options.plugins || false) { 1051 if (options.plugins.supersubs || false) { 1052 $menu.supersubs(options.plugins.supersubs); 1053 } 1054 } 1055 1056 // Apply Superfish to the menu. 1057 $menu.superfish(options.sf); 1058 1059 // Check if we are to apply any other plug-in to it. 1060 if (options.plugins || false) { 1061 if (options.plugins.touchscreen || false) { 1062 $menu.sftouchscreen(options.plugins.touchscreen); 1063 } 1064 if (options.plugins.smallscreen || false) { 1065 $menu.sfsmallscreen(options.plugins.smallscreen); 1066 } 1067 if (options.plugins.supposition || false) { 1068 $menu.supposition(); 1069 } 1070 } 1071 }); 1072 } 1073 }; 1074})(jQuery, Drupal, drupalSettings); 1075;
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.