1/** 2 * @file 3 * A JavaScript file that styles the page with bootstrap classes. 4 * 5 * @see sass/styles.scss for more info 6 */ 7 8// $ passé en paramètre d'IIFE plutôt qu'assigné en global : dxpr_global.min.js (CDN DXPR, 9// chargé pour les comptes content_manager sur le front) déclare `const $` en top-level, 10// une assignation globale `$ = jQuery` lève alors TypeError et bloque tout le fichier. 11(function ($, Drupal, once, window, document, undefined) { 12var glazedMenuState = ''; 13// glazedSettings est absent de drupalSettings tant qu'aucun theme setting glazed n'est configuré (voir glazed_preprocess_html). 14var glazedSettings = drupalSettings.glazedSettings || {}; 15 16Drupal.behaviors.fullScreenSearch = { 17 attach: function(context, settings) { 18 function clearSearchForm() { 19 $searchForm.toggleClass("invisible"), 20 $('body').toggleClass("body--full-screen-search"), 21 setTimeout(function() { 22 $searchFormInput.val("") 23 }, 350) 24 } 25 var $searchButton = $(".full-screen-search-button") 26 , $searchForm = $(".full-screen-search-form") 27 , $searchFormInput = $searchForm.find(".search-query") 28 , escapeCode = 27; 29 $searchButton.on("touchstart click", function(event) { 30 event.preventDefault(), 31 $searchForm.toggleClass("invisible"), 32 $('body').toggleClass("body--full-screen-search"), 33 $searchFormInput.focus() 34 }), 35 $searchForm.on("touchstart click", function($searchButton) { 36 $($searchButton.target).hasClass("search-query") || clearSearchForm() 37 }), 38 $(document).keydown(function(event) { 39 event.which === escapeCode && !$searchForm.hasClass("invisible") && clearSearchForm() 40 }) 41 } 42} 43 44Drupal.behaviors.glazed = { 45 attach: function(context, settings) { 46 // Page Title Background Image Helper 47 var bg_img = $('#page-title-full-width-container').attr('data-bg-img'); 48 if (bg_img) { 49 $('<style>#page-title-full-width-container:after{background-image:url("'+ bg_img +'")}</style>').appendTo('head'); 50 } 51 52 // Menu System 53 var windowHeight = $(window).height(); 54 if ($('#glazed-main-menu .menu').length > 0) { 55 glazedMenuGovernor(document); 56 } 57 58 // Helper classes 59 $('.glazed-util-full-height', context).css('min-height', windowHeight); 60 61 // User page 62 $('.page-user .main-container', context).find('> .row > .col-sm-12') 63 .removeClass('col-sm-12') 64 .addClass('col-sm-8 col-md-offset-2'); 65 66 // Main content layout 67 $('.glazed-util-content-center-4-col .main-container', context).find('> .row > .col-sm-12') 68 .removeClass('col-sm-12') 69 .addClass('col-sm-4 col-md-offset-4'); 70 71 $('.glazed-util-content-center-6-col .main-container', context).find('> .row > .col-sm-12') 72 .removeClass('col-sm-12') 73 .addClass('col-sm-6 col-md-offset-3'); 74 75 $('.glazed-util-content-center-8-col .main-container', context).find('> .row > .col-sm-12') 76 .removeClass('col-sm-12') 77 .addClass('col-sm-8 col-md-offset-2'); 78 79 $('.glazed-util-content-center-10-col .main-container', context).find('> .row > .col-sm-12') 80 .removeClass('col-sm-12') 81 .addClass('col-sm-8 col-md-offset-1'); 82 83 // Messages, position absolutely when overlay header and no page title 84 if (($('.wrap-messages').length > 0) 85 && ($('.glazed-header--overlay').length > 0) 86 && ($('#page-title').length == 0)) 87 $('.wrap-messages', context).css({ 88 'position' : 'absolute', 89 'z-index' : '9999', 90 'right' : '0', 91 }); 92 93 // Breadcrumbs 94 var behaviorGlazedSettings = settings.glazedSettings || {}; 95 if (behaviorGlazedSettings.breadcrumbsSeparator) { 96 var breadcrumbsSeparator = behaviorGlazedSettings.breadcrumbsSeparator; 97 $('.breadcrumb a', context) 98 .after(' <span class="glazed-breadcrumb-spacer">' + breadcrumbsSeparator + '</span> '); 99 } else { 100 $('.breadcrumb a', context) 101 .after(' <span class="glazed-breadcrumb-spacer">/</span> '); 102 } 103 104 // Sidebar nav blocks 105 $('.region-sidebar-first .block .view ul, .region-sidebar-second .block .view ul', context) 106 .addClass('nav'); 107 } 108}; 109 110// Create underscore debounce and throttle functions if they doesn't exist already 111if(typeof _ != 'function'){ 112 window._ = {}; 113 window._.debounce = function(func, wait, immediate) { 114 var timeout, result; 115
116 var later = function(context, args) { 117 timeout = null; 118 if (args) result = func.apply(context, args); 119 }; 120 121 var debounced = restArgs(function(args) { 122 var callNow = immediate && !timeout; 123 if (timeout) clearTimeout(timeout); 124 if (callNow) { 125 timeout = setTimeout(later, wait); 126 result = func.apply(this, args); 127 } else if (!immediate) { 128 timeout = _.delay(later, wait, this, args); 129 } 130 131 return result; 132 }); 133 134 debounced.cancel = function() { 135 clearTimeout(timeout); 136 timeout = null; 137 }; 138 139 return debounced; 140 }; 141 var restArgs = function(func, startIndex) { 142 startIndex = startIndex == null ? func.length - 1 : +startIndex; 143 return function() { 144 var length = Math.max(arguments.length - startIndex, 0); 145 var rest = Array(length); 146 for (var index = 0; index < length; index++) { 147 rest[index] = arguments[index + startIndex]; 148 } 149 switch (startIndex) { 150 case 0: return func.call(this, rest); 151 case 1: return func.call(this, arguments[0], rest); 152 case 2: return func.call(this, arguments[0], arguments[1], rest); 153 } 154 var args = Array(startIndex + 1); 155 for (index = 0; index < startIndex; index++) { 156 args[index] = arguments[index]; 157 } 158 args[startIndex] = rest; 159 return func.apply(this, args); 160 }; 161 }
162 _.delay = restArgs(function(func, wait, args) { 163 return setTimeout(function() { 164 return func.apply(null, args); 165 }, wait); 166 }); 167 168 window._.throttle = function (func, wait, options) { 169 var context, args, result; 170 var timeout = null; 171 var previous = 0; 172 if (!options) options = {}; 173 var later = function () { 174 previous = options.leading === false ? 0 : _.now(); 175 timeout = null; 176 result = func.apply(context, args); 177 if (!timeout) context = args = null; 178 }; 179 return function () { 180 var now = _.now(); 181 if (!previous && options.leading === false) previous = now; 182 var remaining = wait - (now - previous); 183 context = this; 184 args = arguments; 185 if (remaining <= 0 || remaining > wait) { 186 if (timeout) { 187 clearTimeout(timeout); 188 timeout = null; 189 } 190 previous = now; 191 result = func.apply(context, args); 192 if (!timeout) context = args = null; 193 } else if (!timeout && options.trailing !== false) { 194 timeout = setTimeout(later, remaining); 195 } 196 return result; 197 }; 198 }; 199} 200 201$(window).resize(_.debounce(function(){ 202 if ($('#glazed-main-menu .menu').length > 0) { 203 glazedMenuGovernorBodyClass(); 204 glazedMenuGovernor(document); 205 } 206 // Mobile menu open direction. 207 if ((glazedSettings.headerSideDirection === 'right') && $(window).width() <= window.glazedNavBreakpoint){ 208 $('#glazed-main-menu').addClass('glazed-main-menu--to-left'); 209 } 210 else { 211 $('#glazed-main-menu').removeClass('glazed-main-menu--to-left'); 212 } 213 // Fix bug with unstyled content on page load. 214 if ($(window).width() > window.glazedNavBreakpoint && $('.glazed-header--side').length === 0) { 215 $('#glazed-main-menu').css('position', 'relative'); 216 } 217}, 50)); 218 219var navBreak = 'glazedNavBreakpoint' in window ? window.glazedNavBreakpoint : 1200; 220if ($('.glazed-header--sticky').length > 0 && !$('.glazed-header--overlay').length && $(window).width() > navBreak) { 221 var headerHeight = glazedSettings.headerHeight; 222 var headerScroll = glazedSettings.headerOffset; 223 var scroll = 0; 224 225 if (headerHeight && headerScroll) { 226 _.throttle($(window).scroll(function () { 227 scroll = $(window).scrollTop(); 228 if (scroll >= headerScroll && scroll <= headerScroll * 2) { 229 document.getElementsByClassName("wrap-containers")[0].style.cssText = "margin-top:" + +headerHeight + "px"; 230 } else if (scroll < headerScroll) { 231 document.getElementsByClassName("wrap-containers")[0].style.cssText = "margin-top:0"; 232 } 233 }), 100); 234 } 235} 236 237 238function glazedMenuGovernor(context) { 239 // Bootstrap dropdown multi-column smart menu 240 var navBreak = 1200; 241 if('glazedNavBreakpoint' in window) { 242 navBreak = window.glazedNavBreakpoint; 243 } 244 if (($('.body--glazed-header-side').length == 0) && $(window).width() > navBreak) { 245 if (glazedMenuState == 'top') { 246 return false; 247 } 248 $('.html--glazed-nav-mobile--open').removeClass('html--glazed-nav-mobile--open'); 249 $('.glazed-header--side').removeClass('glazed-header--side').addClass('glazed-header--top'); 250 $('#glazed-main-menu .menu__breadcrumbs').remove(); 251 $('.menu__level').removeClass('menu__level').css('top', '100%').css('margin-top', 0).css('height', 'auto'); 252 $('.menu__item').removeClass('menu__item'); 253 $('[data-submenu]').removeAttr('data-submenu'); 254 $('[data-menu]').removeAttr('data-menu'); 255 256 var bodyWidth = $('body').innerWidth(); 257 var margin = 10; 258 $('#glazed-main-menu .menu .dropdown-menu', context) 259 .each(function() { 260 var width = $(this).width(); 261 if ($(this).find('.glazed-megamenu__heading').length > 0) { 262 var columns = $(this).find('.glazed-megamenu__heading').length; 263 } 264 else { 265 var columns = Math.floor($(this).find('li').length / 8) + 1; 266 } 267 if (columns > 2) { 268 $(this).css({ 269 'width' : '100%', // Full Width Mega Menu 270 'left:' : '0', 271 }).parent().css({ 272 'position' : 'static', 273 }).find('.dropdown-menu >li').css({ 274 'width' : 100 / columns + '%', 275 }); 276 } 277 else { 278 var $this = $(this); 279 if (columns > 1) { 280 // Accounts for 1px border. 281 $this 282 .css('min-width', width * columns + 2) 283 .find('>li').css('width', width) 284 } 285 // Workaround for drop down overlapping. 286 // See https://github.com/twbs/bootstrap/issues/13477. 287 var $topLevelItem = $this.parent(); 288 // Set timeout to let the rendering threads catch up. 289 setTimeout(function() { 290 var delta = Math.round(bodyWidth - $topLevelItem.offset().left - $this.outerWidth() - margin); 291 // Only fix items that went out of screen. 292 if (delta < 0) { 293 $this.css('left', delta + 'px'); 294 } 295 }, 0) 296 } 297 }); 298 glazedMenuState = 'top'; 299 // Hit Detection for Header 300 if (($('.tabs--primary').length > 0) && ($('#navbar').length > 0)) { 301 var tabsRect = $('.tabs--primary')[0].getBoundingClientRect(); 302 if (($('.glazed-header--navbar-pull-down').length > 0) && ($('#navbar .container-col').length > 0)) { 303 var pullDownRect = $('#navbar .container-col')[0].getBoundingClientRect(); 304 if (glazedHit(pullDownRect, tabsRect)) { 305 $('.tabs--primary').css('margin-top', pullDownRect.bottom - tabsRect.top + 6); 306 } 307 } 308 else { 309 var navbarRect = $('#navbar')[0].getBoundingClientRect(); 310 if (glazedHit(navbarRect, tabsRect)) { 311 $('.tabs--primary').css('margin-top', navbarRect.bottom - tabsRect.top + 6); 312 } 313 314 } 315 } 316 if (($('#secondary-header').length > 0) && ($('#navbar.glazed-header--overlay').length > 0)) { 317 var secHeaderRect = $('#secondary-header')[0].getBoundingClientRect(); 318 if (glazedHit($('#navbar.glazed-header--overlay')[0].getBoundingClientRect(), secHeaderRect)) { 319 if (glazedSettings.secondHeaderSticky) { 320 $('#navbar.glazed-header--overlay').css('cssText','top:' + secHeaderRect.bottom + 'px !important;'); 321 $('#secondary-header').addClass('glazed-secondary-header--sticky'); 322 } 323 else { 324 if ($('#toolbar-bar').length > 0) { 325 $('#navbar.glazed-header--overlay').css('top', secHeaderRect.bottom); 326 } 327 else { 328 $('#navbar.glazed-header--overlay').css('top', ''); 329 } 330 $('#secondary-header').removeClass('glazed-secondary-header--sticky'); 331 } 332 } 333 } 334 } 335 // Mobile Menu with sliding panels and breadcrumb 336 // @dsee glazed-mobile-nav.js 337 else { 338 if (glazedMenuState == 'side') { 339 return false;
340 } 341 // Temporary hiding while settings up @see #290 342 $('#glazed-main-menu').hide(); 343 // Set up classes 344 $('.glazed-header--top').removeClass('glazed-header--top').addClass('glazed-header--side'); 345 // Remove split-megamenu columns 346 $('#glazed-main-menu .menu .dropdown-menu, #glazed-main-menu .menu .dropdown-menu li').removeAttr('style'); 347 $('#glazed-main-menu .menu').addClass('menu__level'); 348 $('#glazed-main-menu .menu .dropdown-menu').addClass('menu__level'); 349 $('#glazed-main-menu .menu .glazed-megamenu').addClass('menu__level'); 350 $('#glazed-main-menu .menu a').addClass('menu__link'); 351 $('#glazed-main-menu .menu li').addClass('menu__item'); 352 // Set up data attributes 353 $('#glazed-main-menu .menu a.dropdown-toggle').each(function( index ) { 354 $(this).attr('data-submenu', $(this).text()) 355 .next().attr('data-menu', $(this).text()); 356 }); 357 $('#glazed-main-menu .menu a.glazed-megamenu__heading').each(function( index ) { 358 $(this).attr('data-submenu', $(this).text()) 359 .next().attr('data-menu', $(this).text()); 360 }); 361 362 var bc = ($('#glazed-main-menu .menu .dropdown-menu').length > 0); 363 var menuEl = document.getElementById('glazed-main-menu'), 364 mlmenu = new MLMenu(menuEl, { 365 breadcrumbsCtrl : bc, // show breadcrumbs 366 initialBreadcrumb : 'menu', // initial breadcrumb text 367 backCtrl : false, // show back button 368 itemsDelayInterval : 10, // delay between each menu item sliding animation 369 // onItemClick: loadDummyData // callback: item that doesn´t have a submenu gets clicked - onItemClick([event], [inner HTML of the clicked item]) 370 }); 371 372 // Close/open menu function 373 var closeMenu = function () { 374 $('#glazed-menu-toggle').toggleClass( 'navbar-toggle--active' ); 375 $(menuEl).toggleClass( 'menu--open' ); 376 $('html').toggleClass( 'html--glazed-nav-mobile--open' ); 377 }; 378 379 // mobile menu toggle 380 $('#glazed-menu-toggle').click(function() { 381 // once('glazedMenuToggle', '#glazed-menu-toggle').click(function() { 382 closeMenu(); 383 }); 384 $('#glazed-main-menu').css('position', 'fixed').show(); 385 386 // Close menu with click on anchor link 387 $('.menu__link').click(function () { 388 if (!$(this).attr('data-submenu')) { 389 closeMenu(); 390 } 391 }); 392 393 // See if logo or block content overlaps menu and apply correction 394 if ($('.wrap-branding').length > 0) { 395 var brandingBottom = $('.wrap-branding')[0].getBoundingClientRect().bottom; 396 } 397 else { 398 var brandingBottom = 0; 399 } 400 var $lastBlock = $('#glazed-main-menu .block:not(.block-menu)').last(); 401 402 // Show menu after completing setup 403 // See if blocks overlap menu and apply correction 404 if (($('.body--glazed-header-side').length > 0) && ($(window).width() > navBreak) && ($lastBlock.length > 0) && (brandingBottom > 0)) { 405 $('#glazed-main-menu').css('padding-top', brandingBottom + 40); 406 } 407 if (($lastBlock.length > 0)) { 408 var lastBlockBottom = $lastBlock[0].getBoundingClientRect().bottom; 409 $('.menu__breadcrumbs').css('top', lastBlockBottom + 20); 410 $('.menu__level').css('top', lastBlockBottom + 40); 411 var offset = 40 + lastBlockBottom; 412 $('.glazed-header--side .menu__level').css('height', 'calc(100vh - ' + offset + 'px)'); 413 } 414 else if (($('.body--glazed-header-side').length > 0) && ($('.wrap-branding').length > 0) && (brandingBottom > 120)) { 415 $('.menu__breadcrumbs').css('top', brandingBottom + 20); 416 $('.menu__level').css('top', brandingBottom + 40); 417 var offset = 40 + brandingBottom; 418 $('.glazed-header--side .menu__level').css('height', 'calc(100vh - ' + offset + 'px)'); 419 } 420 glazedMenuState = 'side'; 421 } 422} 423 424// Fixed header on mobile on tablet 425var headerHeight = glazedSettings.headerMobileHeight; 426var headerFixed = glazedSettings.headerMobileFixed; 427var navBreak = 'glazedNavBreakpoint' in window ? window.glazedNavBreakp
427oint : 1200; 428 429if (headerFixed && $('.glazed-header').length > 0 && $(window).width() <= navBreak) { 430 if ($('#toolbar-bar').length > 0) { 431 $('#navbar').addClass('header-mobile-admin-fixed'); 432 } 433 if ($(window).width() >= 975) { 434 $('#navbar').addClass('header-mobile-admin-fixed-active'); 435 } else { 436 $('#navbar').removeClass('header-mobile-admin-fixed-active'); 437 } 438 $('.glazed-boxed-container').css('overflow', 'hidden'); 439 $('#toolbar-bar').addClass('header-mobile-fixed'); 440 $('#navbar').addClass('header-mobile-fixed'); 441 $('#secondary-header').css('margin-top', +headerHeight); 442} 443 444function glazedMenuGovernorBodyClass() { 445 var navBreak = 1200; 446 if('glazedNavBreakpoint' in window) { 447 navBreak = window.glazedNavBreakpoint; 448 } 449 if ($(window).width() > navBreak) { 450 $('.body--glazed-nav-mobile').removeClass('body--glazed-nav-mobile').addClass('body--glazed-nav-desktop'); 451 } 452 else { 453 $('.body--glazed-nav-desktop').removeClass('body--glazed-nav-desktop').addClass('body--glazed-nav-mobile'); 454 } 455} 456 457// Accepts 2 getBoundingClientRect objects 458function glazedHit(rect1, rect2) { 459 return !(rect1.right < rect2.left || 460 rect1.left > rect2.right || 461 rect1.bottom < rect2.top || 462 rect1.top > rect2.bottom); 463} 464 465})(jQuery, Drupal, once, this, this.document);
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.