1!function(a){a.jGrowl=function(b,c){0===a("#jGrowl").length&&a('<div id="jGrowl"></div>').addClass(c&&c.position?c.position:a.jGrowl.defaults.position).appendTo(c&&c.appendTo?c.appendTo:a.jGrowl.defaults.appendTo),a("#jGrowl").jGrowl(b,c)},a.fn.jGrowl=function(b,c){if(void 0===c&&a.isPlainObject(b)&&(c=b,b=c.message),a.isFunction(this.each)){var d=arguments;return this.each(function(){void 0===a(this).data("jGrowl.instance")&&(a(this).data("jGrowl.instance",a.extend(new a.fn.jGrowl,{notifications:[],element:null,interval:null})),a(this).data("jGrowl.instance").startup(this)),a.isFunction(a(this).data("jGrowl.instance")[b])?a(this).data("jGrowl.instance")[b].apply(a(this).data("jGrowl.instance"),a.makeArray(d).slice(1)):a(this).data("jGrowl.instance").create(b,c)})}},a.extend(a.fn.jGrowl.prototype,{defaults:{pool:0,header:"",group:"",sticky:!1,position:"top-right",appendTo:"body",glue:"after",theme:"default",themeState:"highlight",corners:"10px",check:250,life:3e3,closeDuration:"normal",openDuration:"normal",easing:"swing",closer:!0,closeTemplate:"×",closerTemplate:"<div>[ close all ]</div>",log:function(){},beforeOpen:function(){},afterOpen:function(){},open:function(){},beforeClose:function(){},close:function(){},click:function(){},animateOpen:{opacity:"show"},animateClose:{opacity:"hide"}},notifications:[],element:null,interval:null,create:function(b,c){var d=a.extend({},this.defaults,c);"undefined"!=typeof d.speed&&(d.openDuration=d.speed,d.closeDuration=d.speed),this.notifications.push({message:b,options:d}),d.log.apply(this.element,[this.element,b,d])},render:function(b){var c=this,d=b.message,e=b.options;e.themeState=""===e.themeState?"":"ui-state-"+e.themeState;var f=a("<div/>").addClass("jGrowl-notification alert "+e.themeState+" ui-corner-all"+(void 0!==e.group&&""!==e.group?" "+e.group:"")).append(a("<button/>").addClass("jGrowl-close").html(e.closeTemplate)).append(a("<div/>").addClass("jGrowl-header").html(e.header)).append(a("<div/>").addClass("jGrowl-message").html(d)).data("jGrowl",e).addClass(e.theme).children(".jGrowl-close").bind("click.jGrowl",function(){return a(this).parent().trigger("jGrowl.beforeClose"),!1}).parent();a(f).bind("mouseover.jGrowl",function(){a(".jGrowl-notification",c.element).data("jGrowl.pause",!0)}).bind("mouseout.jGrowl",function(){a(".jGrowl-notification",c.element).data("jGrowl.pause",!1)}).bind("jGrowl.beforeOpen",function(){e.beforeOpen.apply(f,[f,d,e,c.element])!==!1&&a(this).trigger("jGrowl.open")}).bind("jGrowl.open",function(){e.open.apply(f,[f,d,e,c.element])!==!1&&("after"==e.glue?a(".jGrowl-notification:last",c.element).after(f):a(".jGrowl-notification:first",c.element).before(f),a(this).animate(e.animateOpen,e.openDuration,e.easing,function(){a.support.opacity===!1&&this.style.removeAttribute("filter"),null!==a(this).data("jGrowl")&&"undefined"!=typeof a(this).data("jGrowl")&&(a(this).data("jGrowl").created=new Date),a(this).trigger("jGrowl.afterOpen")}))}).bind("jGrowl.afterOpen",function(){e.afterOpen.apply(f,[f,d,e,c.element])}).bind("click",function(){e.click.apply(f,[f,d,e,c.element])}).bind("jGrowl.beforeClose",function(){e.beforeClose.apply(f,[f,d,e,c.element])!==!1&&a(this).trigger("jGrowl.close")}).bind("jGrowl.close",function(){a(this).data("jGrowl.pause",!0),a(this).animate(e.animateClose,e.closeDuration,e.easing,function(){a.isFunction(e.close)?e.close.apply(f,[f,d,e,c.element])!==!1&&a(this).remove():a(this).remove()})}).trigger("jGrowl.beforeOpen"),""!==e.corners&&void 0!==a.fn.corner&&a(f).corner(e.corners),a(".jGrowl-notification:parent",c.element).length>1&&0===a(".jGrowl-closer",c.element).length&&this.defaults.closer!==!1&&a(this.defaults.closerTemplate).addClass("jGrowl-closer "+this.defaults.themeState+" ui-corner-all").addClass(this.defaults.theme).appendTo(c.element).animate(this.defaults.animateOpen,this.defaults.speed,this.defaults.easing).bind("click.jGrowl",function(){a(this).siblings().trigger("jGrowl.beforeClose"),a.isFunction(c.defaults.closer)&&c.defaults.closer.apply(a(this).parent()[0],[a(this).parent()[0]])})},update:function(){a(this.element).find(".jGrowl-notification:parent").each(function(){void 0!==a(this).data("jGrowl")&&void 0!==a(this).data("jGrowl").created&&a(this).data("jGrowl").created.getTime()+parseInt(a(this).data("jGrowl").life,10)<(new Date).getTime()&&a(this).data("jGrowl").sticky!==!0&&(void 0===a(this).data("jGrowl.pause")||a(this).data("jGrowl.pause")!==!0)&&a(this).trigger("jGrowl.beforeClose")}),this.notifications.length>0&&(0===this.defaults.pool||a(this.element).find(".jGrowl-notification:parent").length<this.defaults.pool)&&this.render(this.notifications.shift()),a(this.element).find(".jGrowl-notification:parent").length<2&&a(this.element).find(".jGrowl-closer").animate(this.defaults.animateClose,this.defaults.speed,this.defaults.easing,function(){a(this).remove()})},startup:function(b){this.element=a(b).addClass("jGrowl").append('<div class="jGrowl-notification"></div>'),this.interval=setInterval(function(){var c=a(b).data("jGrowl.instance");void 0!==c&&c.update()},parseInt(this.defaults.check,10))},shutdown:function(){a(this.element).removeClass("jGrowl").find(".jGrowl-notification").trigger("jGrowl.close").parent().empty(),clearInterval(this.interval)},close:function(){a(this.element).find(".jGrowl-notification").each(function(){a(this).trigger("jGrowl.beforeClose")})}}),a.jGrowl.defaults=a.fn.jGrowl.prototype.defaults}(jQuery); 2; 3/** 4 * @file 5 * nicemessages.js 6 * 7 * Use jGrowl to display messages. 8 */ 9 10/** 11 * Displays messages with jGrowl. 12 */ 13Drupal.behaviors.nicemessages = { 14 attach: function () { 15 if (Drupal.settings.nicemessages) { 16 jQuery.jGrowl.defaults.position = Drupal.settings.nicemessages.position; 17 jQuery.jGrowl.defaults.closerTemplate = '<div>'+Drupal.t('[ close all ]')+'</div>'; 18 if (Drupal.settings.nicemessages.items) { 19 for (i in Drupal.settings.nicemessages.items) { 20 jQuery.jGrowl(Drupal.settings.nicemessages.items[i].content, { 21 life: Drupal.settings.nicemessages.items[i].life, 22 glue: Drupal.settings.nicemessages.items[i].glue, 23 speed: Drupal.settings.nicemessages.items[i].speed, 24 theme: Drupal.settings.nicemessages.items[i].type, 25 sticky: Drupal.settings.nicemessages.items[i].life == 0 26 }); 27 } 28 delete Drupal.settings.nicemessages.items; 29 } 30 } 31 } 32} 33; 34/** 35 * @file 36 * Cookiebot functionality. 37 */ 38 39(function ($, Drupal) { 40 'use strict'; 41 42 var $window = $(window); 43 var renewConsentTriggerEventName = 'cookiebotConsentRenew'; 44 45 /** 46 * Capitalize the first character of a given string. 47 * 48 * @param {string} string 49 * The string to capitalize the first character of. 50 * 51 * @return {string} 52 * The string with the first letter capitalized. 53 */ 54 var capitalizeFirstCharacter = function (string) { 55 return string[0].toUpperCase() + string.substr(1); 56 }; 57 58 /** 59 * Listens to event of a user accepting the use of cookies. 60 * 61 * This is also called on every page load when cookies are already accepted. 62 */ 63 $window.on('CookiebotOnAccept', function () {
64 Drupal.cookiebot.updateCookies(); 65 }); 66 67 /** 68 * Listens to the event of a user declining the use of cookies. 69 * 70 * This is also called on every page load when cookies are already declined. 71 */ 72 $window.on('CookiebotOnDecline', function () { 73 Drupal.cookiebot.updateCookies(); 74 }); 75 76 /** 77 * Listens to event of a user wanting to change their cookies consent. 78 */ 79 $window.on(renewConsentTriggerEventName, function () { 80 if (typeof Cookiebot === 'undefined') { 81 return; 82 } 83 84 Cookiebot.renew(); 85 }); 86 87 /** 88 * Attach Cookiebot renew click event listener. 89 * 90 * @type {Drupal~behavior} 91 */ 92 Drupal.behaviors.cookiebot = { 93 attach: function attach(context, settings) { 94 if (context !== document) { 95 return; 96 } 97 98 Drupal.cookiebot.updateCookies(); 99 100 $('.cookiebot-renew', context).once().on('click', function (event) { 101 event.preventDefault(); 102 103 $window.trigger(renewConsentTriggerEventName); 104 }); 105 106 if (settings.cookiebot.message_placeholder_cookieconsent_optout_marketing_show && settings.cookiebot.message_placeholder_cookieconsent_optout_marketing.length > 0) { 107 var message_placeholder_cookieconsent_optout_marketing = settings.cookiebot.message_placeholder_cookieconsent_optout_marketing.replace('!cookiebot_renew', 'javascript:Cookiebot.renew()'); 108 $('[data-cookieconsent="marketing"][data-src]').each(function () { 109 var cookiebot_from_src_url = ''; 110 if ($(this).attr('data-src').length) { 111 cookiebot_from_src_url = $(this).attr('data-src'); 112 } 113 $(this).once('cb-message-placeholder-cookieconsent-optout-marketing').after(message_placeholder_cookieconsent_optout_marketing.replace(new RegExp('!cookiebot_from_src_url', 'g'), cookiebot_from_src_url)); 114 }); 115 } 116 } 117 }; 118 119 /** 120 * Updates cookies for Cookiebot. 121 * 122 * We set our own cookies to be able to provide integration with other Drupal 123 * modules, without relying on the cookies of Cookiebot, since those are not 124 * part of the public API. 125 */ 126 Drupal.cookiebot = { 127 updateCookies: function updateCookies() { 128 var cookieNames = [ 129 'necessary', 130 'preferences', 131 'statistics', 132 'marketing' 133 ]; 134 135 if (typeof Cookiebot === 'undefined' || Cookiebot.consent === void (0)) { 136 return; 137 } 138 139 $.each(cookieNames, function (index, cookieName) { 140 if (Cookiebot.consent[cookieName] === true && $.cookie('cookiebot-consent--' + cookieName) !== '1') { 141 $.cookie('cookiebot-consent--' + cookieName, '1', { 142 path: '/' 143 }); 144 $window.trigger('cookiebotConsentAccept' + capitalizeFirstCharacter(cookieName)); 145 return; 146 } 147 148 if (Cookiebot.consent[cookieName] === false && $.cookie('cookiebot-consent--' + cookieName) !== '0') { 149 $.cookie('cookiebot-consent--' + cookieName, '0', { 150 path: '/' 151 }); 152 $window.trigger('cookiebotConsentDecline' + capitalizeFirstCharacter(cookieName)); 153 } 154 }); 155 } 156 }; 157 158})(jQuery, Drupal, window); 159; 160/** 161 * @file views_load_more.js 162 * 163 * Handles the AJAX pager for the view_load_more plugin. 164 */ 165(function ($) { 166 167 /** 168 * Provide a series of commands that the server can request the client perform. 169 */ 170 Drupal.ajax.prototype.commands.viewsLoadMoreAppend = function (ajax, response, status) { 171 // Get information from the response. If it is not there, default to 172 // our presets. 173 var wrapper = response.selector ? $(response.selector) : $(ajax.wrapper); 174 var method = response.method || ajax.method; 175 var targetList = response.targetList || ''; 176 var effect = ajax.getEffect(response); 177 var pager_selector = response.options.pager_selector ? response.options.pager_selector : '.pager-load-more'; 178 179 // We don't know what response.data contains: it might be a string of text 180 // without HTML, so don't rely on jQuery correctly iterpreting 181 // $(response.data) as new HTML rather than a CSS selector. Also, if 182 // response.data contains top-level text nodes, they get lost with either 183 // $(response.data) or $('<div></div>').replaceWith(response.data). 184 var new_content_wrapped = $('<div></div>').html(response.data); 185 var new_content = new_content_wrapped.contents(); 186 187 // For legacy reasons, the effects processing code assumes that new_content 188 // consists of a single top-level element. Also, it has not been 189 // sufficiently tested whether attachBehaviors() can be successfully called 190 // with a context object that includes top-level text nodes. However, to 191 // give developers full control of the HTML appearing in the page, and to 192 // enable Ajax content to be inserted in places where DIV elements are not 193 // allowed (e.g., within TABLE, TR, and SPAN parents), we check if the new 194 // content satisfies the requirement of a single top-level element, and 195 // only use the container DIV created above when it doesn't. For more 196 // information, please see http://drupal.org/node/736066. 197 if (new_content.length != 1 || new_content.get(0).nodeType != 1) { 198 new_content = new_content_wrapped; 199 } 200 // If removing content from the wrapper, detach behaviors first. 201 var settings = response.settings || ajax.settings || Drupal.settings; 202 Drupal.detachBehaviors(wrapper, settings); 203 if ($.waypoints != undefined) { 204 $.waypoints('refresh'); 205 } 206 207 // Set up our default query options. This is for advance users that might 208 // change there views layout classes. This allows them to write there own 209 // jquery selector to replace the content with. 210 // Provide sensible defaults for unordered list, ordered list and table 211 // view styles. 212 var content_query = targetList && !response.options.content ? '> .view-content ' + targetList : response.options.content || '> .view-content'; 213 214 // If we're using any effects. Hide the new content before adding it to the DOM. 215 if (effect.showEffect != 'show') { 216 new_content.find(content_query).children().hide(); 217 } 218 219 // Update the pager 220 // Find both for the wrapper as the newly loaded content the direct child 221 // .item-list in case of nested pagers 222 wrapper.find(pager_selector).replaceWith(new_content.find(pager_selector)); 223 224 // Add the new content to the page. 225 wrapper.find(content_query)[method](new_content.find(content_query).children()); 226 227 // Re-class the loaded content. 228 // @todo this is faulty in many ways. first of which is that user may have configured view to not have these classes at all. 229 wrapper.find(content_query).children() 230 .removeClass('views-row-first views-row-last views-row-odd views-row-even') 231 .filter(':first') 232 .addClass('views-row-first') 233 .end() 234 .filter(':last') 235 .addClass('views-row-last') 236 .end() 237 .filter(':even') 238 .addClass('views-row-odd') 239 .end() 240 .filter(':odd') 241 .addClass('views-row-even') 242 .end(); 243 244 if (effect.showEffect != 'show') { 245 wrapper.find(content_query).children(':not(:visible)')[effect.showEffect](effect.showSpeed); 246 } 247 248 // Additional processing over new content 249 wrapper.trigger('views_load_more.new_content', new_content.clone()); 250 251 // Attach all JavaScript behaviors to the new content 252 // Remove the Jquery once Class, TODO: There needs to be a better 253 // way of doing this, look at .removeOnce() :-/ 254 var classes = wrapper.attr('class'); 255 var onceClass = classes.match(/jquery-once-[0-9]*-[a-z]*/); 256 wrapper.removeClass(onceClass[0]); 257 settings = response.settings || ajax.settings || Drupal.settings; 258 Drupal.attachBehaviors(wrapper, settings); 259 }; 260 261 /** 262 * Attaches the AJAX behavior to Views Load More waypoint support. 263 */ 264 Drupal.behaviors.ViewsLoadMore = { 265 attach: function (context, settings) { 266 var default_opts = { 267 offset: '100%' 268 }; 269 270 if (settings && settings.viewsLoadMore && settings.views && settings.views.ajaxViews) { 271 $.each(settings.viewsLoadMore, function(i, setting) { 272 var view = '.view-id-' + setting.view_name + '.view-display-id-' + setting.view_display_id + ' .pager-next a', 273 opts = {}; 274 275 $.extend(opts, default_opts, settings.viewsLoadMore[i].opts); 276 277 $(view).waypoint('destroy'); 278 $(view).waypoint(function(event, direction) { 279 $(view).click(); 280 }, opts); 281 }); 282 } 283 }, 284 detach: function (context, settings, trigger) { 285 if (settings && settings.viewsLoadMore && settings.views && settings.views.ajaxViews) { 286 $.each(settings.viewsLoadMore, function(i, setting) { 287 var view = '.view-id-' + setting.view_name + '.view-display-id-' + setting.view_display_id; 288 if ($(context).is(view)) { 289 $('.pager-next a', view).waypoint('destroy'); 290 } 291 else { 292 $(view, context).waypoint('destroy'); 293 } 294 }); 295 } 296 } 297 }; 298})(jQuery); 299; 300/** 301 * @file 302 * Some basic behaviors and utility functions for Views. 303 */ 304(function ($) { 305 306Drupal.Views = {}; 307 308/** 309 * jQuery UI tabs, Views integration component 310 */ 311Drupal.behaviors.viewsTabs = { 312 attach: function (context) { 313 if ($.viewsUi && $.viewsUi.tabs) { 314 $('#views-tabset').once('views-processed').viewsTabs({ 315 selectedClass: 'active' 316 }); 317 } 318 319 $('a.views-remove-link').once('views-processed').click(function(event) { 320 var id = $(this).attr('id').replace('views-remove-link-', ''); 321 $('#views-row-' + id).hide(); 322 $('#views-removed-' + id).attr('checked', true); 323 event.preventDefault(); 324 }); 325 /** 326 * Here is to handle display deletion 327 * (checking in the hidden checkbox and hiding out the row) 328 */ 329 $('a.display-remove-link') 330 .addClass('display-processed') 331 .click(function() { 332 var id = $(this).attr('id').replace('display-remove-link-', ''); 333 $('#display-row-' + id).hide(); 334 $('#display-removed-' + id).attr('checked', true); 335 return false; 336 }); 337 } 338}; 339 340/** 341 * Helper function to parse a querystring. 342 */ 343Drupal.Views.parseQueryString = function (query) { 344 var args = {}; 345 var pos = query.indexOf('?'); 346 if (pos != -1) { 347 query = query.substring(pos + 1); 348 } 349 var pairs = query.split('&'); 350 for(var i in pairs) { 351 if (typeof(pairs[i]) == 'string') { 352 var pair = pairs[i].split('='); 353 // Ignore the 'q' path argument, if present. 354 if (pair[0] != 'q' && pair[1]) { 355 args[decodeURIComponent(pair[0].replace(/\+/g, ' '))] = decodeURIComponent(pair[1].replace(/\+/g, ' ')); 356 } 357 } 358 } 359 return args; 360}; 361 362/** 363 * Helper function to return a view's arguments based on a path. 364 */ 365Drupal.Views.parseViewArgs = function (href, viewPath) { 366 var returnObj = {}; 367 var path = Drupal.Views.getPath(href); 368 // Ensure we have a correct path. 369 if (viewPath && path.substring(0, viewPath.length + 1) == viewPath + '/') { 370 var args = decodeURIComponent(path.substring(viewPath.length + 1, path.length)); 371 returnObj.view_args = args; 372 returnObj.view_path = path; 373 } 374 return returnObj; 375}; 376 377/** 378 * Strip off the protocol plus domain from an href. 379 */ 380Drupal.Views.pathPortion = function (href) { 381 // Remove e.g. http://example.com if present. 382 var protocol = window.location.protocol; 383 if (href.substring(0, protocol.length) == protocol) { 384 // 2 is the length of the '//' that normally follows the protocol 385 href = href.substring(href.indexOf('/', protocol.length + 2)); 386 } 387 return href; 388}; 389 390/** 391 * Return the Drupal path portion of an href. 392 */ 393Drupal.Views.getPath = function (href) { 394 href = Drupal.Views.pathPortion(href); 395 href = href.substring(Drupal.settings.basePath.length, href.length); 396 // 3 is the length of the '?q=' added to the url without clean urls. 397 if (href.substring(0, 3) == '?q=') { 398 href = href.substring(3, href.length); 399 } 400 var chars = ['#', '?', '&']; 401 for (i in chars) { 402 if (href.indexOf(chars[i]) > -1) { 403 href = href.substr(0, href.indexOf(chars[i])); 404 } 405 } 406 return href; 407}; 408 409})(jQuery); 410; 411(function ($) { 412 413/** 414 * A progressbar object. Initialized with the given id. Must be inserted into 415 * the DOM afterwards through progressBar.element. 416 * 417 * method is the function which will perform the HTTP request to get the 418 * progress bar state. Either "GET" or "POST". 419 * 420 * e.g. pb = new progressBar('myProgressBar'); 421 * some_element.appendChild(pb.element); 422 */ 423Drupal.progressBar = function (id, updateCallback, method, errorCallback) { 424 var pb = this; 425 this.id = id; 426 this.method = method || 'GET'; 427 this.updateCallback = updateCallback; 428 this.errorCallback = errorCallback; 429
430 // The WAI-ARIA setting aria-live="polite" will announce changes after users 431 // have completed their current activity and not interrupt the screen reader. 432 this.element = $('<div class="progress-wrapper" aria-live="polite"></div>'); 433 this.element.html('<div id ="' + id + '" class="progress progress-striped active">' + 434 '<div class="progress-bar" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="0">' + 435 '<div class="percentage sr-only"></div>' + 436 '</div></div>' + 437 '</div><div class="percentage pull-right"></div>' + 438 '<div class="message"> </div>'); 439}; 440 441/** 442 * Set the percentage and status message for the progressbar. 443 */ 444Drupal.progressBar.prototype.setProgress = function (percentage, message) { 445 if (percentage >= 0 && percentage <= 100) { 446 $('div.progress-bar', this.element).css('width', percentage + '%'); 447 $('div.progress-bar', this.element).attr('aria-valuenow', percentage); 448 $('div.percentage', this.element).html(percentage + '%'); 449 } 450 $('div.message', this.element).html(message); 451 if (this.updateCallback) { 452 this.updateCallback(percentage, message, this); 453 } 454}; 455 456/** 457 * Start monitoring progress via Ajax. 458 */ 459Drupal.progressBar.prototype.startMonitoring = function (uri, delay) { 460 this.delay = delay; 461 this.uri = uri; 462 this.sendPing(); 463}; 464 465/** 466 * Stop monitoring progress via Ajax. 467 */ 468Drupal.progressBar.prototype.stopMonitoring = function () { 469 clearTimeout(this.timer); 470 // This allows monitoring to be stopped from within the callback. 471 this.uri = null; 472}; 473 474/** 475 * Request progress data from server. 476 */ 477Drupal.progressBar.prototype.sendPing = function () { 478 if (this.timer) { 479 clearTimeout(this.timer); 480 } 481 if (this.uri) { 482 var pb = this; 483 // When doing a post request, you need non-null data. Otherwise a 484 // HTTP 411 or HTTP 406 (with Apache mod_security) error may result. 485 $.ajax({ 486 type: this.method, 487 url: this.uri, 488 data: '', 489 dataType: 'json', 490 success: function (progress) { 491 // Display errors. 492 if (progress.status == 0) { 493 pb.displayError(progress.data); 494 return; 495 } 496 // Update display. 497 pb.setProgress(progress.percentage, progress.message); 498 // Schedule next timer. 499 pb.timer = setTimeout(function () { pb.sendPing(); }, pb.delay); 500 }, 501 error: function (xmlhttp) { 502 pb.displayError(Drupal.ajaxError(xmlhttp, pb.uri)); 503 } 504 }); 505 } 506}; 507 508/** 509 * Display errors on the page. 510 */ 511Drupal.progressBar.prototype.displayError = function (string) { 512 var error = $('<div class="alert alert-block alert-error"><a class="close" data-dismiss="alert" href="#">×</a><h4>Error message</h4></div>').append(string); 513 $(this.element).before(error).hide(); 514 515 if (this.errorCallback) { 516 this.errorCallback(this); 517 } 518}; 519 520})(jQuery); 521; 522/** 523 * @file 524 * Handles AJAX fetching of views, including filter submission and response. 525 */ 526(function ($) { 527 528/** 529 * Attaches the AJAX behavior to Views exposed filter forms and key View links. 530 */ 531Drupal.behaviors.ViewsAjaxView = {}; 532Drupal.behaviors.ViewsAjaxView.attach = function() { 533 if (Drupal.settings && Drupal.settings.views && Drupal.settings.views.ajaxViews) { 534 $.each(Drupal.settings.views.ajaxViews, function(i, settings) { 535 Drupal.views.instances[i] = new Drupal.views.ajaxView(settings); 536 }); 537 } 538}; 539 540Drupal.views = {}; 541Drupal.views.instances = {}; 542 543/** 544 * Javascript object for a certain view. 545 */ 546Drupal.views.ajaxView = function(settings) { 547 var selector = '.view-dom-id-' + settings.view_dom_id; 548 this.$view = $(selector); 549 550 // Retrieve the path to use for views' ajax. 551 var ajax_path = Drupal.settings.views.ajax_path; 552 553 // If there are multiple views this might've ended up showing up multiple times. 554 if (ajax_path.constructor.toString().indexOf("Array") != -1) { 555 ajax_path = ajax_path[0]; 556 } 557 558 // Check if there are any GET parameters to send to views. 559 var queryString = window.location.search || ''; 560 if (queryString !== '') { 561 // Remove the question mark and Drupal path component if any. 562 var queryString = queryString.slice(1).replace(/q=[^&]+&?|&?render=[^&]+/, ''); 563 if (queryString !== '') { 564 // If there is a '?' in ajax_path, clean url are on and & should be used to add parameters. 565 queryString = ((/\?/.test(ajax_path)) ? '&' : '?') + queryString; 566 } 567 } 568 569 this.element_settings = { 570 url: ajax_path + queryString, 571 submit: settings, 572 setClick: true, 573 event: 'click', 574 selector: selector, 575 progress: { type: 'throbber' } 576 }; 577 578 this.settings = settings; 579
580 // Add the ajax to exposed forms. 581 this.$exposed_form = $('#views-exposed-form-'+ settings.view_name.replace(/_/g, '-') + '-' + settings.view_display_id.replace(/_/g, '-')); 582 this.$exposed_form.once(jQuery.proxy(this.attachExposedFormAjax, this)); 583 584 // Add the ajax to pagers. 585 this.$view 586 // Don't attach to nested views. Doing so would attach multiple behaviors 587 // to a given element. 588 .filter(jQuery.proxy(this.filterNestedViews, this)) 589 .once(jQuery.proxy(this.attachPagerAjax, this)); 590 591 // Add a trigger to update this view specifically. In order to trigger a 592 // refresh use the following code. 593 // 594 // @code 595 // jQuery('.view-name').trigger('RefreshView'); 596 // @endcode 597 // Add a trigger to update this view specifically. 598 var self_settings = this.element_settings; 599 self_settings.event = 'RefreshView'; 600 this.refreshViewAjax = new Drupal.ajax(this.selector, this.$view, self_settings); 601}; 602 603Drupal.views.ajaxView.prototype.attachExposedFormAjax = function() { 604 var button = $('input[type=submit], button[type=submit], input[type=image]', this.$exposed_form); 605 button = button[0]; 606 607 this.exposedFormAjax = new Drupal.ajax($(button).attr('id'), button, this.element_settings); 608}; 609 610Drupal.views.ajaxView.prototype.filterNestedViews= function() { 611 // If there is at least one parent with a view class, this view 612 // is nested (e.g., an attachment). Bail. 613 return !this.$view.parents('.view').size(); 614}; 615 616/** 617 * Attach the ajax behavior to each link. 618 */ 619Drupal.views.ajaxView.prototype.attachPagerAjax = function() { 620 this.$view.find('ul.pager > li > a, th.views-field a, .attachment .views-summary a') 621 .each(jQuery.proxy(this.attachPagerLinkAjax, this)); 622}; 623 624/** 625 * Attach the ajax behavior to a singe link. 626 */ 627Drupal.views.ajaxView.prototype.attachPagerLinkAjax = function(id, link) { 628 var $link = $(link); 629 var viewData = {}; 630 var href = $link.attr('href'); 631 // Construct an object using the settings defaults and then overriding 632 // with data specific to the link. 633 $.extend( 634 viewData, 635 this.settings, 636 Drupal.Views.parseQueryString(href), 637 // Extract argument data from the URL. 638 Drupal.Views.parseViewArgs(href, this.settings.view_base_path) 639 ); 640 641 // For anchor tags, these will go to the target of the anchor rather 642 // than the usual location. 643 $.extend(viewData, Drupal.Views.parseViewArgs(href, this.settings.view_base_path)); 644 645 this.element_settings.submit = viewData; 646 this.pagerAjax = new Drupal.ajax(false, $link, this.element_settings); 647}; 648 649Drupal.ajax.prototype.commands.viewsScrollTop = function (ajax, response, status) { 650 // Scroll to the top of the view. This will allow users 651 // to browse newly loaded content after e.g. clicking a pager 652 // link. 653 var offset = $(response.selector).offset(); 654 // We can't guarantee that the scrollable object should be 655 // the body, as the view could be embedded in something 656 // more complex such as a modal popup. Recurse up the DOM 657 // and scroll the first element that has a non-zero top. 658 var scrollTarget = response.selector; 659 while ($(scrollTarget).scrollTop() == 0 && $(scrollTarget).parent()) { 660 scrollTarget = $(scrollTarget).parent(); 661 } 662 // Only scroll upward 663 if (offset.top - 10 < $(scrollTarget).scrollTop()) { 664 $(scrollTarget).animate({scrollTop: (offset.top - 10)}, 500); 665 } 666}; 667 668})(jQuery); 669;
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.