1(function($) { 2// Add table class 3 $(document).ready(function() { 4 5 // Accessibility issue. Check if the aria-required attribute exists 6 // on an HTML element already holding a required attribute. 7 // If such an element exist, make sure that the aria-required attribute is 'true' 8 let oRequired = jQuery('.article').find(`[aria-required='']`); 9 if (oRequired.attr('required') == 'required' || oRequired.attr('required')) { 10 oRequired.attr('aria-required', 'true'); 11 } 12 13 $('article table').each(function () { 14 var s = $(this).attr('style'); 15 classes = ''; 16 if (s !== undefined) { 17 const styles = s.split(";"); 18 styles.forEach(function countEntry(entry) { 19 t = entry.split(':'); 20 if (t[0] == 'border-style' || t[0] == 'border-bottom-style') { 21 classes = t[1]; 22 } 23 }, this); 24 } 25 $(this).addClass('table'); 26 $(this).addClass(classes); 27 $(this).addClass($(this).data('classes')); 28 $(this).wrap('<div class="table-responsive "></div>'); 29 }); 30 $('article ul:not(.breadcrumb, .list-unstyled, .dropdown-menu), article ol, article dl').each(function () { 31 $(this).addClass('rdl-list'); 32 }); 33 34 $('div[data-drupal-messages-fallback]').detach().prependTo('#mainContent .page-container'); 35 function moveMessages() { 36 if ($('#rdl-block-message').length == 0) { 37 $('#rdl-system-message').parent().detach().prependTo('#mainHeader .rdl-system-messages-wrapper'); 38 } 39 // Move message to the top of the block 40 if ($('#rdl-block-message').length == 1) { 41 $('#rdl-system-message').parent().removeClass('container-fluid').addClass('container'); 42 const errorDiv = document.querySelector('.rdl-system-message-error'); 43 if (errorDiv) { 44 errorDiv.setAttribute('tabindex', '-1'); 45 errorDiv.focus({ preventScroll: true }); 46 errorDiv.scrollIntoView({ behavior: 'smooth', block: 'start' }); 47 } 48 } 49 } 50 51 // Because they are not there on load 52 window.setTimeout(moveMessages, 10); 53 }); 54})(jQuery); 55 56// TODO: Replaced by working patternlab. 57(function($) { 58 $buttons = $('.rdl-filter-btn-group'); 59 $buttons.find('.rdl-show-more').click(function(e) { 60 $buttons = $('.rdl-filter-btn-group'); 61 $buttons.toggleClass('show-all-filters'); 62 }); 63})(jQuery); 64 65(function ($) { 66 $(document).ready(function () { 67 var gateway_nids = ''; 68 $('[data-type=download-spot]').each(function(){ 69 gateway_nids = gateway_nids + ',' + $(this).data('id'); 70 }); 71 Cookies.set('gateway_nids', gateway_nids, { path: '/', sameSite: 'lax'}); 72 }); 73})(jQuery, window.Cookies); 74 75 76/* Functions to be overwritte from the RISE repo concerning the content spot banner. 77Should later be implemented in the RISE repo, since functionality is needed on other sites aswell, imho. 78Functionality makes it possible to have several content spot banners with filters on the same site. */ 79 80('use strict'); 81 82function filterSelectedDisplay(display, filter) { 83 //get all the content spot button sections 84 let drupalButtonGroup = document.querySelectorAll('.rdl-filter-btn-group'); 85 //run through them 86 Array.prototype.slice.call(drupalButtonGroup).forEach(function(selection) { 87 //check if their data-heading matches the display sent from the function 88 if(selection.getAttribute('data-heading') === display) { 89 //get the buttons from that selected content spot banner section 90 let buttons = selection.querySelectorAll('button'); 91 //run through the buttons 92 Array.prototype.slice.call(buttons).forEach(function(button) { 93 //check if the button matches the filter sent from the function 94 if(button.innerHTML === filter) { 95 //if it does, set the active class. 96 button.classList.add('active'); 97 } 98 else { 99 //if it does not, make sure the class is removed. 100 button.classList.remove('active'); 101 } 102 }); 103 } 104 }); 105 //get all the content spot blurb sections 106 let drupalContentSpotFilterGroup = document.querySelectorAll('.rdl-grid-container-wrapper'); 107 //run through them 108 Array.prototype.slice.call(drupalContentSpotFilterGroup).forEac
108h(function(selection) { 109 //check if their data-heading matches the display sent from the function 110 if(selection.getAttribute('data-heading') === display) { 111 //get all the blurbs in the section 112 let blurbs = selection.querySelectorAll('[data-filter]'); 113 //run through the blurbs 114 Array.prototype.slice.call(blurbs).forEach(function(blurb) { 115 //get an array of all the data-filters the given blurb 116 let blurbFilters = blurb.getAttribute('data-filter').split(','); 117 //remove the last one, since we know it'll be empty because of the comma. 118 blurbFilters.pop(); 119 //declare variable to keep track if we should show the blurb 120 let beShown = false; 121 //run through the filters on the given blurb 122 Array.prototype.slice.call(blurbFilters).forEach(function(filterOption) { 123 //if the filter option matches the filter given to the function, set true 124 if(filterOption === filter) { 125 beShown = true; 126 } 127 }); 128 //when the run trough them all is complete, check if the blurb should be shown. 129 if(beShown === true) { 130 //if it should, remove the hide class from the element. 131 blurb.classList.remove('hide'); 132 } 133 else { 134 //if it should not, add the hide class to the element. 135 blurb.classList.add('hide'); 136 } 137 }); 138 } 139 }); 140 //finally, update the URL based on the filter and the display. 141 filterURLmanipulation(display, filter); 142} 143 144function filterURLmanipulation(display, filter) { 145 //get the URL and split it at the first questionmark 146 let siteArg = window.location.href.split(/\?(.*)/)[1]; 147 if(siteArg != undefined) { 148 siteArg = '/?' + siteArg.split(/\#(.*)/)[0]; 149 } 150 else { 151 siteArg = ''; 152 } 153 let queryStr = window.location.href.split(/\#(.*)/); 154 //remove that last element, since we get a last entry to the array which is emtpy. 155 queryStr.pop(); 156 //if we only have the URL, add the new filter. 157 if(queryStr.length === 0) { 158 //add filter based on the arguments. 159 let hashString = display + '=' + filter; 160 location.href = siteArg + '#' + hashString; 161 } 162 //if the URL already have filters added. 163 else if(queryStr.length > 0) { 164 //create holding variables. 165 let requestObj = {}; 166 let level1 = []; 167 //split the rest of the array at the & to get each content spot id and their associated filter option. 168 level1 = queryStr[1].split('&'); 169 //run though the filters 170 for (let i = 0; i < level1.length; i++) { 171 //split the filter into id and filter option. 172 let level2 = level1[i].split('='); 173 //store the values in the object. 174 requestObj[level2[0]] = level2[1]; 175 } 176 //create holding variables. 177 let paramString = ''; 178 let paramSet = false; 179 //run through the object. 180 Object.keys(requestObj).forEach(function(item, index) { 181 //if the display given matches the argument from the fuction, we update the filter option. 182 if(item === display) { 183 requestObj[item] = filter; 184 //and we indicate the filter already exists in the URL. 185 paramSet = true; 186 } 187 //if this is the first loop, add the id and filter to the string without & before. 188 if(index === 0) { 189 paramString += item + '=' + requestObj[item]; 190 } 191 //else add it with & before. 192 else { 193 paramString += '&' + item + '=' + requestObj[item]; 194 } 195 }); 196 //If the argument filter was not in the object of already existing filters, add it afterwards. 197 if(paramSet === false) { 198 paramString = paramString += '&' + display + '=' + filter; 199 } 200 //set the filters in the URL. 201 location.href = siteArg + '#' + paramString; 202 } 203} 204 205function showFiltersFromURL() { 206 //get the URL and split it at the first questionmark 207 let queryStr = window.location.href.split(/\#(.*)/); 208 //remove that last element, since we get a last entry to the array which is emtpy. 209 queryStr.pop(); 210 //remove the URL, thus leaving us with the arguments. 211 queryStr.shift(); 212 //check if we even have a filter pressent 213 if(queryStr.length >= 1) { 214 //splut the filters if possible. 215 let queryParams = queryStr[0].split('&'); 216 //run through the filters. 217 for(let x=0;x<queryParams.length;x++) { 218 //split the selected param into the display and the filter. 219 let selectedParams = queryParams[x].split('='); 220 //run the function to display selected filter on selected display. 221 filterSelectedDisplay(selectedParams[0], decodeURI(selectedParams[1])); 222 } 223 } 224} 225 226(function ($, Drupal, cookies) { 227 $(document).ready(function () { 228 if ($('ul.rdl-secondary-nav > li.dropdown-relative').find('.collapse').length == 1 && (cookie
228s.get('dropdown_showed') == undefined || cookies.get('dropdown_showed') != 1)) { 229 $('ul.rdl-secondary-nav > li.dropdown-relative').find('.collapse').css('display', 'inline-flex'); 230 const d = new Date(); 231 d.setTime(d.getTime() + (365 * 24 * 60 * 60 * 1000)); 232 let expires = "expires=" + d.toUTCString(); 233 document.cookie = "dropdown_showed=1;" + expires + ";path=/" 234 setTimeout(() => { 235 $('ul.rdl-secondary-nav > li.dropdown-relative').find('.collapse').removeAttr('style'); 236 }, 5000); 237 } 238 }); 239})(jQuery, Drupal, window.Cookies); 240 241// Accessibility issue. If a Bootstrap-select is present, 242// append the aria-controls with the id of the nearest select 243(function ($, Drupal) { 244 Drupal.behaviors.customBootstrapSelect = { 245 attach: function (context, settings) { 246 // Initialize the MutationObserver 247 var observer = new MutationObserver(function (mutations) { 248 mutations.forEach(function (mutation) { 249 // Check if the mutation added new nodes 250 if (mutation.addedNodes.length) { 251 $(mutation.addedNodes).find('button[role="combobox"]').each(function () { 252 var selectId = $(this).closest('.bootstrap-select').find('select').attr('id'); 253 $(this).attr('aria-controls', selectId); 254 }); 255 } 256 }); 257 }); 258 259 // Observe the document body for changes 260 observer.observe(document.body, { 261 childList: true, 262 subtree: true 263 }); 264 265 // Run immediately in case the elements are already present 266 $('button[role="combobox"]').each(function () { 267 var selectId = $(this).closest('.bootstrap-select').find('select').attr('id'); 268 $(this).attr('aria-controls', selectId); 269 }); 270 } 271 }; 272 273 $(document).ready(function() { 274 $('.rdl-overlay-link').on('focus', function () { 275 $(this).parent().find('.rdl-hero-content .row').addClass("hero-focus"); 276 }); 277 $('.rdl-overlay-link').on('blur', function () { 278 $(this).parent().find('.rdl-hero-content .row').removeClass("hero-focus"); 279 }); 280 $('.rdl-card-link .rdl-overlay-link').on('mouseenter', function() { 281 $(this).parent().find('.rdl-spot-header a').css("text-decoration", "underline"); 282 }); 283 $('.rdl-card-link .rdl-overlay-link').on('mouseleave', function() { 284 $(this).parent().find('.rdl-spot-header a').css("text-decoration", "none"); 285 }); 286 }); 287})(jQuery, Drupal); 288 289(function ($, Drupal) { 290 $(window).on('load', function () { 291 function setHeroButtonPlacement() { 292 const $button = $('.rdl-hero-first .rdl-hero-button'); 293 const $lead = $('.rdl-hero .rdl-hero-lead'); 294 295 if ($button.length && $lead.length) { 296 const top = $lead.outerHeight() + 90; 297 $button.css({ 298 top: top + 'px', 299 opacity: 1 300 }); 301 // Repaint parent since Chrome can't position absolute items in a clip-path on page-load. 302 $button.parent().style.transform = 'translateZ(0)'; 303 } 304 } 305 // Use "double" calls (requestAnimationFrame) so Chrome will render the button correct on page-load. 306 requestAnimationFrame(function () { 307 requestAnimationFrame(setHeroButtonPlacement); 308 }); 309 $(window).on('resize', setHeroButtonPlacement); 310 311 }); 312})(jQuery, Drupal); 313 314// Check if we have a form error. If so, set focus on first element with invalid data 315(function ($, Drupal) { 316 $(document).ready(function () { 317 $('.webform-submission-form .is-invalid:first').focus(); 318 }); 319})(jQuery); 320 321// Handle aria-expanded and sr-only-text for fact spots 322(function ($, Drupal) { 323 Drupal.behaviors.rdlToggleSpot = { 324 attach: function (context, settings) { 325 $('.rdl-toggle-spot-button', context).each(function () { 326 let $button = $(this); 327 let openText = $button.attr('data-open-text'); 328 let closedText = $button.attr('data-closed-text'); 329 let expanded = $button.attr('aria-expanded'); 330 let $controls = $('#' + $button.attr('aria-controls')); 331 332 $button.on('click', function() { 333 if (expanded === "false") { 334 $(this).attr('aria-expanded', 'true'); 335 $(this).attr('title', closedText); 336 $(this).find('.sr-only').text(closedText); 337 $controls.removeAttr('hidden'); 338 $controls.removeAttr('inert'); 339 } 340 else { 341 $(this).attr('aria-expanded', 'false'); 342 $(this).attr('title', openText); 343 $(this).find('.sr-only').text(openText); 344 $controls.attr('hidden', ''); 345 $controls.attr('inert', ''); 346 } 347 expanded = $(this).attr('aria-expanded'); 348 }); 349 }); 350 } 351 }; 352})(jQuery, Drupal); 353 354
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.