vendor: 11,960 bytes, lines 1-6
1/*! 2 Colorbox 1.6.4 3 license: MIT 4 http://www.jacklmoore.com/colorbox 5*/ 6(function(t,e,i){function n(i,n,o){var r=e.createElement(i);return n&&(r.id=Z+n),o&&(r.style.cssText=o),t(r)}function o(){return i.innerHeight?i.innerHeight:t(i).height()}function r(e,i){i!==Object(i)&&(i={}),this.cache={},this.el=e,this.value=function(e){var n;return void 0===this.cache[e]&&(n=t(this.el).attr("data-cbox-"+e),void 0!==n?this.cache[e]=n:void 0!==i[e]?this.cache[e]=i[e]:void 0!==X[e]&&(this.cache[e]=X[e])),this.cache[e]},this.get=function(e){var i=this.value(e);return t.isFunction(i)?i.call(this.el,this):i}}function h(t){var e=W.length,i=(A+t)%e;return 0>i?e+i:i}function a(t,e){return Math.round((/%/.test(t)?("x"===e?E.width():o())/100:1)*parseInt(t,10))}function s(t,e){return t.get("photo")||t.get("photoRegex").test(e)}function l(t,e){return t.get("retinaUrl")&&i.devicePixelRatio>1?e.replace(t.get("photoRegex"),t.get("retinaSuffix")):e}function d(t){"contains"in x[0]&&!x[0].contains(t.target)&&t.target!==v[0]&&(t.stopPropagation(),x.focus())}function c(t){c.str!==t&&(x.add(v).removeClass(c.str).addClass(t),c.str=t)}function g(e){A=0,e&&e!==!1&&"nofollow"!==e?(W=t("."+te).filter(function(){var i=t.data(this,Y),n=new r(this,i);return n.get("rel")===e}),A=W.index(_.el),-1===A&&(W=W.add(_.el),A=W.length-1)):W=t(_.el)}function u(i){t(e).trigger(i),ae.triggerHandler(i)}function f(i){var o;if(!G){if(o=t(i).data(Y),_=new r(i,o),g(_.get("rel")),!U){U=$=!0,c(_.get("className")),x.css({visibility:"hidden",display:"block",opacity:""}),I=n(se,"LoadedContent","width:0; height:0; overflow:hidden; visibility:hidden"),b.css({width:"",height:""}).append(I),j=T.height()+k.height()+b.outerHeight(!0)-b.height(),D=C.width()+H.width()+b.outerWidth(!0)-b.width(),N=I.outerHeight(!0),z=I.outerWidth(!0);var h=a(_.get("initialWidth"),"x"),s=a(_.get("initialHeight"),"y"),l=_.get("maxWidth"),f=_.get("maxHeight");_.w=Math.max((l!==!1?Math.min(h,a(l,"x")):h)-z-D,0),_.h=Math.max((f!==!1?Math.min(s,a(f,"y")):s)-N-j,0),I.css({width:"",height:_.h}),J.position(),u(ee),_.get("onOpen"),O.add(F).hide(),x.focus(),_.get("trapFocus")&&e.addEventListener&&(e.addEventListener("focus",d,!0),ae.one(re,function(){e.removeEventListener("focus",d,!0)})),_.get("returnFocus")&&ae.one(re,function(){t(_.el).focus()})}var p=parseFloat(_.get("opacity"));v.css({opacity:p===p?p:"",cursor:_.get("overlayClose")?"pointer":"",visibility:"visible"}).show(),_.get("closeButton")?B.html(_.get("close")).appendTo(b):B.appendTo("<div/>"),w()}}function p(){x||(V=!1,E=t(i),x=n(se).attr({id:Y,"class":t.support.opacity===!1?Z+"IE":"",role:"dialog",tabindex:"-1"}).hide(),v=n(se,"Overlay").hide(),L=t([n(se,"LoadingOverlay")[0],n(se,"LoadingGraphic")[0]]),y=n(se,"Wrapper"),b=n(se,"Content").append(F=n(se,"Title"),R=n(se,"Current"),P=t('<button type="button"/>').attr({id:Z+"Previous"}),K=t('<button type="button"/>').attr({id:Z+"Next"}),S=t('<button type="button"/>').attr({id:Z+"Slideshow"}),L),B=t('<button type="button"/>').attr({id:Z+"Close"}),y.append(n(se).append(n(se,"TopLeft"),T=n(se,"TopCenter"),n(se,"TopRight")),n(se,!1,"clear:left").append(C=n(se,"MiddleLeft"),b,H=n(se,"MiddleRight")),n(se,!1,"clear:left").append(n(se,"BottomLeft"),k=n(se,"BottomCenter"),n(se,"BottomRight"))).find("div div").css({"float":"left"}),M=n(se,!1,"position:absolute; width:9999px; visibility:hidden; display:none; max-width:none;"),O=K.add(P).add(R).add(S)),e.body&&!x.parent().length&&t(e.body).append(v,x.append(y,M))}function m(){function i(t){t.which>1||t.shiftKey||t.altKey||t.metaKey||t.ctrlKey||(t.preventDefault(),f(this))}return x?(V||(V=!0,K.click(function(){J.next()}),P.click(function(){J.prev()}),B.click(function(){J.close()}),v.click(function(){_.get("overlayClose")&&J.close()}),t(e).bind("keydown."+Z,function(t){var e=t.keyCode;U&&_.get("escKey")&&27===e&&(t.preventDefault(),J.close()),U&&_.get("arrowKey")&&W[1]&&!t.altKey&&(37===e?(t.preventDefault(),P.click()):39===e&&(t.preventDefault(),K.click()))}),t.isFunction(t.fn.on)?t(e).on("click."+Z,"."+te,i):t("."+te).live("click."+Z,i)),!0):!1}function w(){var e,o,r,h=J.prep,d=++le;if($=!0,q=!1,u(he),u(ie),_.get("onLoad"),_.h=_.get("height")?a(_.get("height"),"y")-N-j:_.get("innerHeight")&&a(_.get("innerHeight"),"y"),_.w=_.get("width")?a(_.get("width"),"x")-z-D:_.get("innerWidth")&&a(_.get("innerWidth"),"x"),_.mw=_.w,_.mh=_.h,_.get("maxWidth")&&(_.mw=a(_.get("maxWidth"),"x")-z-D,_.mw=_.w&&_.w<_.mw?_.w:_.mw),_.get("maxHeight")&&(_.mh=a(_.get("maxHeight"),"y")-N-j,_.mh=_.h&&_.h<_.mh?_.h:_.mh),e=_.get("href"),Q=setTimeout(function(){L.show()},100),_.get("inline")){var c=t(e).eq(0);r=t("<div>").hide().insertBefore(c),ae.one(he,function(){r.replaceWith(c)}),h(c)}else _.get("iframe")?h(" "):_.get("html")?h(_.get("html")):s(_,e)?(e=l(_,e),q=_.get("createImg"),t(q).addClass(Z+"Photo").bind("error."+Z,function(){h(n(se,"Error").html(_.get("imgError")))}).one("load",function(){d===le&&setTimeout(function(){var e;_.get("retinaImage")&&i.devicePixelRatio>1&&(q.height=q.height/i.devicePixelRatio,q.width=q.width/i.devicePixelRatio),_.get("scalePhotos")&&(o=function(){q.height-=q.height*e,q.width-=q.width*e},_.mw&&q.width>_.mw&&(e=(q.width-_.mw)/q.width,o()),_.mh&&q.height>_.mh&&(e=(q.height-_.mh)/q.height,o())),_.h&&(q.style.marginTop=Math.max(_.mh-q.height,0)/2+"px"),W[1]&&(_.get("loop")||W[A+1])&&(q.style.cursor="pointer",t(q).bind("click."+Z,function(){J.next()})),q.style.width=q.width+"px",q.style.height=q.height+"px",h(q)},1)}),q.src=e):e&&M.load(e,_.get("data"),function(e,i){d===le&&h("error"===i?n(se,"Error").html(_.get("xhrError")):t(this).contents())})}var v,x,y,b,T,C,H,k,W,E,I,M,L,F,R,S,K,P,B,O,_,j,D,N,z,A,q,U,$,G,Q,J,V,X={html:!1,photo:!1,iframe:!1,inline:!1,transition:"elastic",speed:300,fadeOut:300,width:!1,initialWidth:"600",innerWidth:!1,maxWidth:!1,height:!1,initialHeight:"450",innerHeight:!1,maxHeight:!1,scalePhotos:!0,scrolling:!0,opacity:.9,preloading:!0,className:!1,overlayClose:!0,escKey:!0,arrowKey:!0,top:!1,bottom:!1,left:!1,right:!1,fixed:!1,data:void 0,closeButton:!0,fastIframe:!0,open:!1,reposition:!0,loop:!0,slideshow:!1,slideshowAuto:!0,slideshowSpeed:2500,slideshowStart:"start slideshow",slideshowStop:"stop slideshow",photoRegex:/\.(gif|png|jp(e|g|eg)|bmp|ico|webp|jxr|svg)((#|\?).*)?$/i,retinaImage:!1,retinaUrl:!1,retinaSuffix:"@2x.$1",current:"image {current} of {total}",previous:"previous",next:"next",close:"close",xhrError:"This content failed to load.",imgError:"This image failed to load.",returnFocus:!0,trapFocus:!0,onOpen:!1,onLoad:!1,onComplete:!1,onCleanup:!1,onClosed:!1,rel:function(){return this.rel},href:function(){return t(this).attr("href")},title:function(){return this.title},createImg:function(){var e=new Image,i=t(this).data("cbox-img-attrs");return"object"==typeof i&&t.each(i,function(t,i){e[t]=i}),e},createIframe:function(){var i=e.createElement("iframe"),n=t(this).data("cbox-iframe-attrs");return"object"==typeof n&&t.each(n,function(t,e){i[t]=e}),"frameBorder"in i&&(i.frameBorder=0),"allowTransparency"in i&&(i.allowTransparency="true"),i.name=(new Date).getTime(),i.allowFullscreen=!0,i}},Y="colorbox",Z="cbox",te=Z+"Element",ee=Z+"_open",ie=Z+"_load",ne=Z+"_complete",oe=Z+"_cleanup",re=Z+"_closed",he=Z+"_purge",ae=t("<a/>"),se="div",le=0,de={},ce=function(){function t(){clearTimeout(h)}function e(){(_.get("loop")||W[A+1])&&(t(),h=setTimeout(J.next,_.get("slideshowSpeed")))}function i(){S.html(_.get("slideshowStop")).unbind(s).one(s,n),ae.bind(ne,e).bind(ie,t),x.removeClass(a+"off").addClass(a+"on")}function n(){t(),ae.unbind(ne,e).unbind(ie,t),S.html(_.get("slideshowStart")).unbind(s).one(s,function(){J.next(),i()}),x.removeClass(a+"on").addClass(a+"off")}function o(){r=!1,S.hide(),t(),ae.unbind(ne,e).unbind(ie,t),x.removeClass(a+"off "+a+"on")}var r,h,a=Z+"Slideshow_",s="click."+Z;return function(){r?_.get("slideshow")||(ae.unbind(oe,o),o()):_.get("slideshow")&&W[1]&&(r=!0,ae.one(oe,o),_.get("slideshowAuto")?i():n(),S.show())}}();t[Y]||(t(p),J=t.fn[Y]=t[Y]=function(e,i){var n,o=this;return e=e||{},t.isFunction(o)&&(o=t("<a/>"),e.open=!0),o[0]?(p(),m()&&(i&&(e.onComplete=i),o.each(function(){var i=t.data(this,Y)||{};t.data(this,Y,t.extend(i,e))}).addClass(te),n=new r(o[0],e),n.get("open")&&f(o[0])),o):o},J.position=function(e,i){function n(){T[0].style.width=k[0].style.width=b[0].style.width=parseInt(x[0].style.width,10)-D+"px",b[0].style.height=C[0].style.height=H[0].style.height=parseInt(x[0].style.height,10)-j+"px"}var r,h,s,l=0,d=0,c=x.offset();if(E.unbind("resize."+Z),x.css({top:-9e4,left:-9e4}),h=E.scrollTop(),s=E.scrollLeft(),_.get("fixed")?(c.top-=h,c.left-=s,x.css({position:"fixed"})):(l=h,d=s,x.css({position:"absolute"})),d+=_.get("right")!==!1?Math.max(E.width()-_.w-z-D-a(_.get("right"),"x"),0):_.get("left")!==!1?a(_.get("left"),"x"):Math.round(Math.max(E.width()-_.w-z-D,0)/2),l+=_.get("bottom")!==!1?Math.max(o()-_.h-N-j-a(_.get("bottom"),"y"),0):_.get("top")!==!1?a(_.get("top"),"y"):Math.round(Math.max(o()-_.h-N-j,0)/2),x.css({top:c.top,left:c.left,visibility:"visible"}),y[0].style.width=y[0].style.height="9999px",r={width:_.w+z+D,height:_.h+N+j,top:l,left:d},e){var g=0;t.each(r,function(t){return r[t]!==de[t]?(g=e,void 0):void 0}),e=g}de=r,e||x.css(r),x.dequeue().animate(r,{duration:e||0,complete:function(){n(),$=!1,y[0].style.width=_.w+z+D+"px",y[0].style.height=_.h+N+j+"px",_.get("reposition")&&setTimeout(function(){E.bind("resize."+Z,J.position)},1),t.isFunction(i)&&i()},step:n})},J.resize=function(t){var e;U&&(t=t||{},t.width&&(_.w=a(t.width,"x")-z-D),t.innerWidth&&(_.w=a(t.innerWidth,"x")),I.css({width:_.w}),t.height&&(_.h=a(t.height,"y")-N-j),t.innerHeight&&(_.h=a(t.innerHeight,"y")),t.innerHeight||t.height||(e=I.scrollTop(),I.css({height:"auto"}),_.h=I.height()),I.css({height:_.h}),e&&I.scrollTop(e),J.position("none"===_.get("transition")?0:_.get("speed")))},J.prep=function(i){function o(){return _.w=_.w||I.width(),_.w=_.mw&&_.mw<_.w?_.mw:_.w,_.w}function a(){return _.h=_.h||I.height(),_.h=_.mh&&_.mh<_.h?_.mh:_.h,_.h}if(U){var d,g="none"===_.get("transition")?0:_.get("speed");I.remove(),I=n(se,"LoadedContent").append(i),I.hide().appendTo(M.show()).css({width:o(),overflow:_.get("scrolling")?"auto":"hidden"}).css({height:a()}).prependTo(b),M.hide(),t(q).css({"float":"none"}),c(_.get("className")),d=function(){function i(){t.support.opacity===!1&&x[0].style.removeAttribute("filter")}var n,o,a=W.length;U&&(o=function(){clearTimeout(Q),L.hide(),u(ne),_.get("onComplete")},F.html(_.get("title")).show(),I.show(),a>1?("string"==typeof _.get("current")&&R.html(_.get("current").replace("{current}",A+1).replace("{total}",a)).show(),K[_.get("loop")||a-1>A?"show":"hide"]().html(_.get("next")),P[_.get("loop")||A?"show":"hide"]().html(_.get("previous")),ce(),_.get("preloading")&&t.each([h(-1),h(1)],function(){var i,n=W[this],o=new r(n,t.data(n,Y)),h=o.get("href");h&&s(o,h)&&(h=l(o,h),i=e.createElement("img"),i.src=h)})):O.hide(),_.get("iframe")?(n=_.get("createIframe"),_.get("scrolling")||(n.scrolling="no"),t(n).attr({src:_.get("href"),"class":Z+"Iframe"}).one("load",o).appendTo(I),ae.one(he,function(){n.src="//about:blank"}),_.get("fastIframe")&&t(n).trigger("load")):o(),"fade"===_.get("transition")?x.fadeTo(g,1,i):i())},"fade"===_.get("transition")?x.fadeTo(g,0,function(){J.position(0,d)}):J.position(g,d)}},J.next=function(){!$&&W[1]&&(_.get("loop")||W[A+1])&&(A=h(1),f(W[A]))},J.prev=function(){!$&&W[1]&&(_.get("loop")||A)&&(A=h(-1),f(W[A]))},J.close=function(){U&&!G&&(G=!0,U=!1,u(oe),_.get("onCleanup"),E.unbind("."+Z),v.fadeTo(_.get("fadeOut")||0,0),x.stop().fadeTo(_.get("fadeOut")||0,0,function(){x.hide(),v.hide(),u(he),I.remove(),setTimeout(function(){G=!1,u(re),_.get("onClosed")},1)}))},J.remove=function(){x&&(x.stop(),t[Y].close(),x.stop(!1,!0).remove(),v.remove(),G=!1,x=null,t("."+te).removeData(Y).removeClass(te),t(e).unbind("click."+Z).unbind("keydown."+Z))},J.element=function(){return t(_.el)},J.settings=X)})(jQuery,document,window);
6; 7(function ($) { 8 9Drupal.behaviors.initColorbox = { 10 attach: function (context, settings) { 11 if (!$.isFunction($.colorbox) || typeof settings.colorbox === 'undefined') { 12 return; 13 } 14 15 if (settings.colorbox.mobiledetect && window.matchMedia) { 16 // Disable Colorbox for small screens. 17 var mq = window.matchMedia("(max-device-width: " + settings.colorbox.mobiledevicewidth + ")"); 18 if (mq.matches) { 19 return; 20 } 21 } 22 23 $('.colorbox', context) 24 .once('init-colorbox') 25 .colorbox(settings.colorbox); 26 27 $(context).bind('cbox_complete', function () { 28 Drupal.attachBehaviors('#cboxLoadedContent'); 29 }); 30 } 31}; 32 33})(jQuery); 34; 35 36 37 38/** 39 * @file dhtml_menu.js 40 * The Javascript code for DHTML Menu 41 */ 42 43 44(function($) { 45Drupal.dhtmlMenu = {}; 46Drupal.dhtmlMenu.animation = {show:{}, hide:{}, count:0}; 47 48/** 49 * Initialize the module's JS functions 50 */ 51Drupal.behaviors.dhtmlMenu = { 52 attach: function() { 53 var settings = Drupal.settings.dhtmlMenu; 54 55 // Initialize the animation effects from the settings. 56 for (i in settings.animation.effects) { 57 if (settings.animation.effects[i]) { 58 Drupal.dhtmlMenu.animation.show[i] = 'show'; 59 Drupal.dhtmlMenu.animation.hide[i] = 'hide'; 60 Drupal.dhtmlMenu.animation.count++; 61 } 62 } 63 64 // Sanitize by removing "expanded" on menus already marked "collapsed". 65 $('li.dhtml-menu.collapsed.expanded').removeClass('expanded'); 66 67 /* Relevant only on "open-only" menus: 68 * The links of expanded items should be marked for emphasis. 69 */ 70 if (settings.nav == 'open') { 71 $('li.dhtml-menu.expanded').addClass('dhtml-menu-open'); 72 } 73 74 /* Relevant only when hovering: 75 * 76 * If a context menu is opened (as most users do when opening links in a 77 * new tab), the mouseleave event will be triggered. Although the context 78 * menu still works, having the menu close underneath it is confusing. 79 * 80 * This code will "freeze" the menu's collapse if the body is left 81 * (which happens when a context menu opens), and only release it when the cursor 82 * reenters the menu. 83 * 84 * Note that due to the order in which events are called, 85 * the hovering collapse must work asynchronously so 86 * this event is triggered before the collapse. 87 */ 88 else if (settings.nav == 'hover') { 89 var freeze = false; 90 $('ul.menu').mouseenter(function() {freeze = false}); 91 $('body').mouseleave(function() {freeze = true}); 92 } 93 94 /* Relevant only on bullet-icon expansion: 95 * Create the markup for the bullet overlay, and the amount to shift it to the right in RTL mode. 96 */ 97 else if (settings.nav == 'bullet') { 98 var bullet = $('<a href="#" class="dhtml-menu-icon"></a>'); 99 var rtl = $('html').attr('dir') == 'rtl' ? Math.ceil($('.menu li').css('margin-right').replace('px', '')) + 1 : 0; 100 } 101 102 /* Relevant only when adding cloned links: 103 * Create the markup for the cloned list item container. 104 */ 105 else if (settings.nav == 'clone') { 106 // Note: a single long class is used here to avoid matching the .dhtml-menu.leaf selector later on. 107 var cloned = $('<li class="leaf dhtml-menu-cloned-leaf"></li>'); 108 } 109 110 /* Add jQuery effects and listeners to all menu items. */ 111 $('ul.menu li.dhtml-menu:not(.leaf)').each(function() { 112 var li = $(this); 113 var link = $(this).find('a:first'); 114 var ul = $(this).find('ul:first'); 115 116 // Only work on menus with an actual sub-menu. 117 if (link.length && ul.length) { 118 /* When using cloned items: 119 * - Clone the menu link and mark it as a clone. 120 */ 121 if (settings.nav == 'clone') { 122 link.clone().prependTo(ul).wrap(cloned); 123 } 124 125 /* When using double-click: 126 * - Add a dblclick event handler that allows the normal link action to complete. 127 */ 128 else if (settings.nav == 'doubleclick') { 129 link.dblclick(function(e) { 130 return true; 131 }); 132 } 133 134 /* When using bullet expansion: 135 * - Change the icon to a folder image 136 * - Add the clickable overlay and its handler 137 * - In RTL mode, shift the overlay to the right of the text. 138 * - @TODO: Explore whether "float:right" in dhtml_menu-rtl.css could solve this. 139 */ 140 else if (settings.nav == 'bullet') { 141 li.addClass('dhtml-folder'); 142 var b = bullet.clone().prependTo(link).click(function(e) { 143 Drupal.dhtmlMenu.toggleMenu(li, link, ul); 144 if (settings.effects.remember) { 145 Drupal.dhtmlMenu.cookieSet(); 146 } 147 return false;
148 }); 149 150 // When using RTL, each overlay must be shifted to the other side of the link text, individually. 151 if (rtl) { 152 // Shift the overlay right by the width of the text and the distance between text and icon. 153 b.css('right', '-' + (Math.ceil(link.css('width').replace('px', '')) + rtl) + 'px'); 154 } 155 } 156 157 /* When using hover expansion: 158 * - Add mouse-hovering events. 159 */ 160 else if (settings.nav == 'hover') { 161 link.mouseenter(function(e) { 162 Drupal.dhtmlMenu.switchMenu(li, link, ul, true); 163 }); 164 li.mouseleave(function(e) { 165 // Only collapse the menu if it was initially collapsed. 166 if (li.hasClass('start-collapsed')) { 167 /* As explained earlier, this event fires before the body event. 168 * We need to wait to make sure that the user isn't browsing a 169 * context menu right now, in which case the menu isn't collapsed. 170 */ 171 setTimeout(function() { 172 if (!freeze) { 173 Drupal.dhtmlMenu.switchMenu(li, link, ul, false); 174 } 175 }, 10); 176 } 177 }); 178 } 179 180 /* When using menus that cannot collapse: 181 * Toggle the menu normally, but only if the menu is closed. 182 */ 183 else if (settings.nav == 'open') { 184 link.click(function(e) { 185 // Don't collapse expanded menus. 186 if (li.hasClass('expanded')) { 187 return true; 188 } 189 Drupal.dhtmlMenu.toggleMenu(li, link, ul); 190 $('.dhtml-menu-open').removeClass('dhtml-menu-open'); 191 $('li.dhtml-menu.expanded').addClass('dhtml-menu-open'); 192 return false; 193 }); 194 } 195 196 // These three options make links simply toggle when clicked. 197 if (settings.nav == 'clone' || settings.nav == 'doubleclick' || settings.nav == 'none') { 198 link.click(function(e) { 199 Drupal.dhtmlMenu.toggleMenu(li, link, ul); 200 if (settings.effects.remember) { 201 Drupal.dhtmlMenu.cookieSet(); 202 } 203 return false; 204 }); 205 } 206 } 207 }); 208 209 // When using LTR, all icons can be shifted as one, as the text width is not relevant. 210 if (settings.nav == 'bullet' && !rtl) { 211 // Shift overlay to the left by the width of the icon and the distance between icon and text. 212 if ($('.menu li').hasClass('margin-left')) { 213 var shift = '-' + (Math.ceil(($('.menu li').css('margin-left').replace('px', ''))) + 16) + 'px'; 214 // Shift the overlay using a negative left-hand offset, and the text using a negative right-hand margin. 215 $('.dhtml-menu-icon').css('left', shift).css('margin-right', shift); 216 } 217 } 218 } 219} 220 221/** 222 * Toggles the menu's state between open and closed. 223 * 224 * @param li 225 * Object. The <li> element that will be expanded or collapsed. 226 * @param link 227 * Object. The <a> element representing the menu link anchor. 228 * @param ul 229 * Object. The <ul> element containing the sub-items. 230 */ 231Drupal.dhtmlMenu.toggleMenu = function(li, link, ul) { 232 // Make it open if closed, close if open. 233 Drupal.dhtmlMenu.switchMenu(li, link, ul, !li.hasClass('expanded')); 234} 235 236/** 237 * Switches the menu's state to a defined value. 238 * This function does nothing if the menu is in the target state already. 239 * 240 * @param li 241 * Object. The <li> element that will be expanded or collapsed. 242 * @param link 243 * Object. The <a> element representing the menu link anchor. 244 * @param ul 245 * Object. The <ul> element containing the sub-items. 246 */ 247Drupal.dhtmlMenu.switchMenu = function(li, link, ul, open) { 248 // No need for switching. Menu is already in desired state. 249 if (open == li.hasClass('expanded')) { 250 return; 251 } 252 253 var effects = Drupal.settings.dhtmlMenu.effects; 254 255 if (open) { 256 Drupal.dhtmlMenu.animate(ul, 'show'); 257 li.removeClass('collapsed').addClass('expanded'); 258 259 // If the siblings effect is on, close all sibling menus. 260 if (effects.siblings != 'none') { 261 var id = li.attr('id'); 262 /* Siblings are all open menus that are neither parents nor children of this menu. 263 * First, mark this item's children for exclusion. 264 */ 265 li.find('li').addClass('own-children-temp'); 266 267 // If the relativity option is on, select only the siblings that have the same root 268 if (effects.siblings == 'close-same-tree') { 269 var root = li.parent(); 270 } 271 else { 272 var root = $('ul.menu'); 273 } 274 var siblings = root.find('li.expanded').not('.own-children-temp').not('#' + id); 275 276 // If children should not get closed automatically... 277 if (effects.children == 'none') { 278 // Remove items that are currently hidden from view (do not close these). 279 $('li.collapsed li.expanded').addClass('sibling-children-temp'); 280 // Only close the top-most open sibling, not its children. 281 siblings.find('li.expanded').addClass('sibling-children-temp'); 282 siblings = $(siblings).not('.sibling-children-temp'); 283 } 284 285 // The temp classes can now be removed. 286 $('.own-children-temp, .sibling-children-temp') 287 .removeClass('own-children-temp') 288 .removeClass('sibling-children-temp'); 289 290 Drupal.dhtmlMenu.animate(siblings.find('ul:first'), 'hide'); 291 siblings.removeClass('expanded').addClass('collapsed'); 292 } 293 } 294 else { 295 Drupal.dhtmlMenu.animate(ul, 'hide'); 296 li.removeClass('expanded').addClass('collapsed'); 297 298 // If children are closed automatically, find and close them now. 299 if (effects.children == 'close-children') { 300 // If a sub-menu closes in the forest and nobody sees it, is animation a waste of performance? Yes. 301 li.find('li.expanded') 302 .removeClass('expanded').addClass('collapsed') 303 .find('ul:first').css('display', 'none'); 304 } 305 } 306} 307 308/** 309 * Animate a specific block element using the configured DHTML effects. 310 * 311 * @param element 312 * The element to be animated. DHTML Menu only animates <ul> elements, 313 * but this could in theory be any block (not inline) element. 314 * 315 * @param action 316 * One of either 'show' or 'hide'. 317 */ 318Drupal.dhtmlMenu.animate = function(element, action) { 319 var effects = Drupal.dhtmlMenu.animation; 320 var speed = Drupal.settings.dhtmlMenu.animation.speed; 321
322 if (effects.count) { 323 element.animate(effects[action], speed * 1); 324 } 325 else { 326 element.css('display', action == 'show' ? 'block' : 'none'); 327 } 328} 329 330/** 331 * Saves the dhtml_menu cookie. 332 */ 333Drupal.dhtmlMenu.cookieSet = function() { 334 var expanded = new Array(); 335 $('li.expanded').each(function() { 336 expanded.push(this.id); 337 }); 338 document.cookie = 'dhtml_menu=' + expanded.join(',') + ';path=/'; 339} 340 341})(jQuery); 342 343; 344(function(c,q){var m="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==";c.fn.imagesLoaded=function(f){function n(){var b=c(j),a=c(h);d&&(h.length?d.reject(e,b,a):d.resolve(e));c.isFunction(f)&&f.call(g,e,b,a)}function p(b){k(b.target,"error"===b.type)}function k(b,a){b.src===m||-1!==c.inArray(b,l)||(l.push(b),a?h.push(b):j.push(b),c.data(b,"imagesLoaded",{isBroken:a,src:b.src}),r&&d.notifyWith(c(b),[a,e,c(j),c(h)]),e.length===l.length&&(setTimeout(n),e.unbind(".imagesLoaded", 345p)))}var g=this,d=c.isFunction(c.Deferred)?c.Deferred():0,r=c.isFunction(d.notify),e=g.find("img").add(g.filter("img")),l=[],j=[],h=[];c.isPlainObject(f)&&c.each(f,function(b,a){if("callback"===b)f=a;else if(d)d[b](a)});e.length?e.bind("load.imagesLoaded error.imagesLoaded",p).each(function(b,a){var d=a.src,e=c.data(a,"imagesLoaded");if(e&&e.src===d)k(a,e.isBroken);else if(a.complete&&a.naturalWidth!==q)k(a,0===a.naturalWidth||0===a.naturalHeight);else if(a.readyState||a.complete)a.src=m,a.src=d}): 346n();return d?d.promise(g):g}})(jQuery); 347; 348/** 349 * @file 350 * JS for Responsive Panels Regions. 351 */ 352 353(function ($) { 354 355 "use strict"; 356 357 // These variables are used for handling the mobile menus on screen resize 358 var isMobile = false; 359 var mobileMenus = []; 360 var tracker = 1; 361 362 function setCookie(cname, cvalue, exdays) { 363 var d = new Date(); 364 d.setTime(d.getTime() + (exdays*24*60*60*1000)); 365 var expires = "expires="+d.toUTCString(); 366 document.cookie = cname + "=" + cvalue + "; " + expires + "; path=/"; 367 } 368 369 function getCookie(cname) { 370 var name = cname + "="; 371 var ca = document.cookie.split(';'); 372 for(var i=0; i<ca.length; i++) { 373 var c = ca[i]; 374 while (c.charAt(0)==' ') c = c.substring(1); 375 if (c.indexOf(name) == 0) return c.substring(name.length,c.length); 376 } 377 return ""; 378 } 379 380 function saveState(position) { 381 // save the toggle state in cookie 382 // Cookie plugin not loaded for anonymous users 383 if ($.cookie) { 384 var state = $('body').hasClass('oa-responsive-region-' + position + '-on'); 385 setCookie("oa-responsive-regions-" + position, state, 365) 386 } 387 } 388 389 function getState(position) { 390 // return the cookie state 391 if ($.cookie) { 392 var state = getCookie("oa-responsive-regions-" + position); 393 return state; 394 } 395 return false; 396 } 397 398 function debounce(func, wait, immediate) { 399 var timeout; 400 return function() { 401 var context = this, args = arguments; 402 var later = function() { 403 timeout = null; 404 if (!immediate) func.apply(context, args); 405 }; 406 var callNow = immediate && !timeout; 407 clearTimeout(timeout); 408 timeout = setTimeout(later, wait); 409 if (callNow) func.apply(context, args); 410 }; 411 } 412 413 function maxSidebarHeight() { 414 var region = $('.oa-responsive-primary'); 415 var viewport = $(window).height(); 416 if (region.length) { 417 var toolbarHeight = 0; 418 var toolbar = $('.panel-panel-inner .oa-responsive-region-bottom.oa-responsive-fixed'); 419 if (toolbar.length) { 420 toolbarHeight += $(toolbar).height(); 421 $(region).css('padding-bottom', $(toolbar).height()); 422 } 423 var toolbar = $('.panel-panel-inner .oa-responsive-region-top.oa-responsive-fixed'); 424 if (toolbar.length) { 425 toolbarHeight += $(toolbar).height(); 426 $(region).css('padding-top', $(toolbar).height()); 427 } 428 viewport = viewport - toolbarHeight; 429 var h = region.height(); 430 if (h < viewport) { 431 $('.oa-responsive-region-right').each(function() { 432 $(this).height(viewport); 433 }); 434 $('.oa-responsive-region-left').each(function() { 435 $(this).height(viewport); 436 }); 437 } 438 } 439 } 440 441 function setMenu() { 442 if (isMobile) { 443 // wire the mobile admin 444 if (($('#toolbar-menu-button').length > 0) && ($('#oa-navbar-admin').length > 0)) { 445 $('#navbar-tray .navbar-menu-administration').attr('menu-desktop', tracker) 446 .children('ul').attr('menu-item', tracker).appendTo("#oa-navbar-admin .oa-navbar-inner"); 447 tracker++; 448 } 449 else { 450 $('.oa-navbar button.navbar-toggle.admin').hide(); 451 } 452 453 // move each menu, Bootstrap handles the menu toggle 454 $.each(mobileMenus, function(i, val) { 455 $("."+val+"-mobile-menu").each(function() { 456 if ($(this).hasClass('oa-mobile-expand')) { 457 // defer expanded items 458 } 459 else { 460 $(this).find('.pane-content').appendTo("#oa-navbar-" + val + " .oa-navbar-inner"); 461 } 462 }); 463 }); 464 // Now handle submenus to be appended and expanded 465 $.each(mobileMenus, function(i, val) { 466 $("."+val+"-mobile-menu").each(function() { 467 if ($(this).hasClass('oa-mobile-expand')) { 468 var item = $(this).find('.pane-content ul.dropdown-menu').appendTo("#oa-navbar-" + val + " .oa-navbar-inner"); 469 item.addClass('oa-mobile-expanded'); 470 } 471 }); 472 }); 473 } 474 } 475
476 function fixMobileMenus() { 477 if ($('button.navbar-toggle').is(':visible') != isMobile) { 478 if (isMobile == true) { 479 //there was a change, if isMobile was true the change is to false and is now desktop 480 //here we want to move the menu items back 481 for (var i = 1; i <= tracker; i++) { 482 $('.oa-navbar').find("[menu-item='" + i +"']").appendTo("[menu-desktop='" + i +"']"); 483 } 484 } 485 isMobile = $('button.navbar-toggle').is(':visible'); 486 setMenu(); 487 } 488 } 489 490 function fixColumnWidthOnResize() { 491 $('.oa-responsive-primary').each(function () { 492 var wrapper = $(this).parent().parent(); 493 var getInline = $(wrapper).attr('style'); 494 var inlineWidth = getInline.indexOf('width'); 495 496 if (($(window).width() < 992) && (inlineWidth > -1)) { 497 // Screen smaller than 992 and we have a width already set 498 // We need to clear the width and bring back the first style property 499 $(wrapper).attr('style', 'display: block;'); 500 } else if (($(window).width() > 991 && (inlineWidth == -1))) { 501 // Screen is larger than 991 and we do not have a width set yet 502 // We need to calculate the width again and set it 503 var wrapperLeft = $('.oa-responsive-region-left').outerWidth(); 504 var width = $(wrapper).outerWidth() + wrapperLeft; 505 var percent = Math.floor(width / $(wrapper).parent().outerWidth() * 100); 506 $(wrapper).attr('style', 'display: block; width: ' + percent + '%;'); 507 } 508 }); 509 } 510 511 Drupal.behaviors.responsive_panels_regions = { 512 attach: function(context) { 513 function getStyle(el){ 514 // To determine if width uses % or px, we need to use getComputedStyle 515 // But it only works when display is none. 516 var display = window.getComputedStyle(el).getPropertyValue("display"); 517 el.style.display = "none"; 518 var width = window.getComputedStyle(el).getPropertyValue("width"); 519 el.style.display = display; 520 return width; 521 } 522 $('.oa-responsive-regions-toggle', context).each(function () { 523 $(this).bind('click', function() { 524 var position = $(this).data().position; 525 Drupal.ResponsivePanelsRegions.toggleRegion(position); 526 }); 527 }); 528 // Compute the sizes of the responsive regions 529 var widths = {left: 0, right: 0, top: 0, bottom: 0}; 530 var heights = {left: 0, right: 0, top: 0, bottom: 0}; 531 $('.panel-panel-inner > .oa-responsive-region', context).each(function () { 532 if ($(this).css('position') == 'absolute') { 533 var position = $(this).data().position; 534 var wrapper = $(this).parent().parent(); 535 widths[position] += $(wrapper).outerWidth(); 536 heights[position] += $(wrapper).outerHeight(); 537 } 538 }); 539 // We need to copy the css classes from the panels pane div to its 540 // parent grid element (parent.parent) 541 $('.panel-panel-inner > .oa-responsive-region', context).each(function () { 542 var position = $(this).data().position; 543 var wrapper = $(this).parent().parent(); 544 if ((position != 'center') && (position != 'fluid')) { 545 $(wrapper).addClass($(this).attr('class')); 546 // Prevent absolute positioning on parent row when bar is fixed and expanded 547 if ($(wrapper).hasClass('oa-responsive-expand') && $(wrapper).hasClass('oa-responsive-fixed')) { 548 $(wrapper).removeClass('oa-responsive-region-' + position); 549 } 550 // Prevent parent row from being fixed 551 $(wrapper).removeClass('oa-responsive-fixed'); 552 } 553 // Regions are initially hidden in css to avoid flicker, so show them now 554 $(this).css('display', 'block'); 555 $(wrapper).parent().addClass('oa-responsive-region-row-' + position); 556 }); 557 // Now adjust the size of the primary region 558 $('.oa-responsive-primary', context).each(function () { 559 var wrapper = $(this).parent().parent(); 560 var width = $(wrapper).outerWidth() + widths.left + widths.right; 561 var percent = Math.floor(width / $(wrapper).parent().outerWidth() * 100); 562 var style = getStyle($(wrapper).get(0)); 563 // If the original width used % then compute new % otherwise pixels 564 if (style && (style != 'auto')) { 565 if (style.indexOf('%') >= 0) { 566 $(wrapper).css('width', percent + '%'); 567 } 568 else { 569 $(wrapper).width(width); 570 } 571 } 572 }); 573 $('.oa-responsive-regions-toggle', context).each(function () { 574 // Restore saved cookie states 575 var position = $(this).data().position; 576 if (getState(position) == 'true') { 577 Drupal.ResponsivePanelsRegions.showRegion(position); 578 } 579 }); 580 } 581 }; 582 583 Drupal.behaviors.mobile_nav_behavior = { 584 attach: function(context) { 585 isMobile = $('button.navbar-toggle').is(':visible'); 586 587 mobileMenus = []; 588 // Determine which menu toggles are on page 589 $('button.navbar-toggle').each(function () { 590 var menuid = $(this).data('target'); 591 menuid = menuid.replace("#oa-navbar-", ""); 592 mobileMenus.push(menuid); 593 }); 594 595 tracker = 1; 596 597 // Handle image in user toggle specially 598 var userImg = $('.user-mobile-menu .user-badge img'); 599 if (userImg.length > 0) { 600 var currentUserImg = $('.navbar-toggle.user img'); 601 // if there is a user image (logged in), then put it into the mobile button 602 // but only once. 603 if (currentUserImg.length == 0) { 604 userImg.clone().appendTo('.navbar-toggle.user'); 605 } 606 } 607 else { 608 // if no image, then move the Login link 609 var currentLink = $('.navbar-toggle.user .user-badge'); 610 if (currentLink.length == 0) { 611 $('.user-mobile-menu .user-badge').clone().appendTo('.navbar-toggle.user'); 612 } 613 } 614 $.each(mobileMenus, function(i, val) { 615 $("."+val+"-mobile-menu").find('.pane-content').each( function() { 616 $(this).attr('menu-item', tracker).parent().attr('menu-desktop', tracker); 617 tracker++; 618 }); 619 }); 620 621 setMenu(); 622 } 623 }; 624 625 Drupal.ResponsivePanelsRegions = Drupal.ResponsivePanelsRegions || { 626 toggleRegion: function(position) { 627 $('body').toggleClass('oa-responsive-region-' + position + '-on'); 628 $('.btn-' + position).toggleClass('btn-active'); 629 saveState(position); 630 }, 631 // Provide some helper classes. 632 showRegion: function(position) { 633 $('body').addClass('oa-responsive-region-' + position + '-on'); 634 $('.btn-' + position).addClass('btn-active'); 635 saveState(position); 636 }, 637 hideRegion: function(position) { 638 $('body').removeClass('oa-responsive-region-' + position + '-on'); 639 $('.btn-active').removeClass('btn-active'); 640 saveState(position); 641 } 642 }; 643 644 var sidebarHeight = debounce(function(){ 645 maxSidebarHeight(); 646 }, 250); 647 var fixColumnWidth = debounce(function(){ 648 fixColumnWidthOnResize(); 649 }, 250); 650 var moveMobileMenus = debounce(function(){ 651 fixMobileMenus(); 652 }, 250); 653 654 window.addEventListener('load', sidebarHeight); 655 window.addEventListener('resize', sidebarHeight); 656 window.addEventListener('resize', fixColumnWidth); 657 window.addEventListener('resize', moveMobileMenus); 658 659}
659)(jQuery); 660; 661 662/** 663 * @file: Popup dialog interfaces for the media project. 664 * 665 * Drupal.media.popups.mediaBrowser 666 * Launches the media browser which allows users to pick a piece of media. 667 * 668 * Drupal.media.popups.mediaStyleSelector 669 * Launches the style selection form where the user can choose what 670 * format/style they want their media in. 671 */ 672 673(function ($) { 674namespace('Drupal.media.popups'); 675 676/** 677 * Media browser popup. Creates a media browser dialog. 678 * 679 * @param {function} 680 * onSelect Callback for when dialog is closed, received (Array media, Object 681 * extra); 682 * @param {Object} 683 * globalOptions Global options that will get passed upon initialization of 684 * the browser. @see Drupal.media.popups.mediaBrowser.getDefaults(); 685 * @param {Object} 686 * pluginOptions Options for specific plugins. These are passed to the plugin 687 * upon initialization. If a function is passed here as a callback, it is 688 * obviously not passed, but is accessible to the plugin in 689 * Drupal.settings.variables. Example: 690 * pluginOptions = {library: {url_include_patterns:'/foo/bar'}}; 691 * @param {Object} 692 * widgetOptions Options controlling the appearance and behavior of the modal 693 * dialog. @see Drupal.media.popups.mediaBrowser.getDefaults(); 694 */ 695Drupal.media.popups.mediaBrowser = function (onSelect, globalOptions, pluginOptions, widgetOptions) { 696 // Get default dialog options. 697 var options = Drupal.media.popups.mediaBrowser.getDefaults(); 698 699 // Add global, plugin and widget options. 700 options.global = $.extend({}, options.global, globalOptions); 701 options.plugins = pluginOptions; 702 options.widget = $.extend({}, options.widget, widgetOptions); 703 704 // Find the URL of the modal iFrame. 705 var browserSrc = options.widget.src; 706 707 if ($.isArray(browserSrc) && browserSrc.length) { 708 browserSrc = browserSrc[browserSrc.length - 1]; 709 } 710 711 // Create an array of parameters to send along to the iFrame. 712 var params = {}; 713 714 // Add global field widget settings and plugin information. 715 $.extend(params, options.global); 716 params.plugins = options.plugins; 717 718 // Append the list of parameters to the iFrame URL as query parameters. 719 browserSrc += '&' + $.param(params); 720 721 // Create an iFrame with the iFrame URL. 722 var mediaIframe = Drupal.media.popups.getPopupIframe(browserSrc, 'mediaBrowser'); 723 724 // Attach an onLoad event. 725 mediaIframe.bind('load', options, options.widget.onLoad); 726 727 // Create an array of Dialog options. 728 var dialogOptions = options.dialog; 729 730 // Setup the dialog buttons. 731 var ok = Drupal.t('OK'); 732 var notSelected = Drupal.t('You have not selected anything!'); 733 734 dialogOptions.buttons[ok] = function () { 735 // Find the current file selection. 736 var selected = this.contentWindow.Drupal.media.browser.selectedMedia; 737 738 // Alert the user if a selection has yet to be made. 739 if (selected.length < 1) { 740 alert(notSelected); 741 742 return; 743 } 744 745 // Select the file. 746 onSelect(selected); 747 748 // Close the dialog. 749 $(this).dialog('close'); 750 }; 751 752 // Create a jQuery UI dialog with the given options. 753 var dialog = mediaIframe.dialog(dialogOptions); 754 755 // Allow the dialog to react to re-sizing, scrolling, etc. 756 Drupal.media.popups.sizeDialog(dialog); 757 Drupal.media.popups.resizeDialog(dialog); 758 Drupal.media.popups.scrollDialog(dialog); 759 Drupal.media.popups.overlayDisplace(dialog.parents(".ui-dialog")); 760 761 return mediaIframe; 762}; 763 764/** 765 * Retrieves a list of default settings for the media browser. 766 * 767 * @return 768 * An array of default settings. 769 */ 770Drupal.media.popups.mediaBrowser.getDefaults = function () { 771 return { 772 global: { 773 types: [], // Types to allow, defaults to all. 774 enabledPlugins: [] // If provided, a list of plugins which should be enabled. 775 }, 776 widget: { // Settings for the actual iFrame which is launched. 777 src: Drupal.settings.media.browserUrl, // Src of the media browser (if you want to totally override it) 778 onLoad: Drupal.media.popups.mediaBrowser.mediaBrowserOnLoad // Onload function when iFrame loads. 779 }, 780 dialog: Drupal.media.popups.getDialogOptions() 781 }; 782}; 783 784/** 785 * Sets up the iFrame buttons. 786 */ 787Drupal.media.popups.mediaBrowser.mediaBrowserOnLoad = function (e) { 788 var options = e.data; 789 790 // Ensure that the iFrame is defined. 791 if (typeof this.contentWindow.Drupal.media === 'undefined' || typeof 792 this.contentWindow.Drupal.media.browser === 'undefined') { 793 return; 794 } 795 796 // Check if a selection has been made and press the 'ok' button. 797 if (this.contentWindow.Drupal.media.browser.selectedMedia.length > 0) { 798 var ok = Drupal.t('OK'); 799 var ok_func = $(this).dialog('option', 'buttons')[ok]; 800 801 ok_func.call(this); 802 803 return; 804 } 805}; 806 807/** 808 * Finalizes the selection of a file. 809 * 810 * Alerts the user if a selection has yet to be made, triggers the file 811 * selection and closes the modal dialog. 812 */ 813Drupal.media.popups.mediaBrowser.finalizeSelection = function () { 814 // Find the current file selection. 815 var selected = this.contentWindow.Drupal.media.browser.selectedMedia; 816 817 // Alert the user if a selection has yet to be made. 818 if (selected.length < 1) { 819 alert(notSelected); 820 821 return; 822 } 823 824 // Select the file. 825 onSelect(selected); 826 827 // Close the dialog. 828 $(this).dialog('close'); 829}; 830 831/** 832 * Style chooser Popup. Creates a dialog for a user to choose a media style. 833 * 834 * @param mediaFile 835 * The mediaFile you are requesting this formatting form for. 836 * @todo: should this be fid? That's actually all we need now. 837 * 838 * @param Function 839 * onSubmit Function to be called when the user chooses a media style. Takes 840 * one parameter (Object formattedMedia). 841 * 842 * @param Object 843 * options Options for the mediaStyleChooser dialog. 844 */ 845Drupal.media.popups.mediaStyleSelector = function (mediaFile, onSelect, options) { 846 var defaults = Drupal.media.popups.mediaStyleSelector.getDefaults(); 847 848 // @todo: remove this awful hack :( 849 if (typeof defaults.src === 'string' ) { 850 defaults.src = defaults.src.replace('-media_id-', mediaFile.fid) + '&fields=' + encodeURIComponent(JSON.stringify(mediaFile.fields)); 851 } 852 else { 853 var src = defaults.src.shift(); 854 855 defaults.src.unshift(src); 856 defaults.src = src.replace('-media_id-', mediaFile.fid) + '&fields=' + encodeURIComponent(JSON.stringify(mediaFile.fields)); 857 } 858 859 options = $.extend({}, defaults, options); 860 861 // Create an iFrame with the iFrame URL. 862 var mediaIframe = Drupal.media.popups.getPopupIframe(options.src, 'mediaStyleSelector'); 863 864 // Attach an onLoad event. 865 mediaIframe.bind('load', options, options.onLoad); 866 867 // Create an array of Dialog options. 868 var dialogOptions = Drupal.media.popups.getDialogOptions(); 869 870 // Setup the dialog buttons. 871 var ok = Drupal.t('OK'); 872 var notSelected = Drupal.t('Very sorry, there was an unknown error embedding media.'); 873 874 dialogOptions.buttons[ok] = function () { 875 // Find the current file selection. 876 var formattedMedia = this.contentWindow.Drupal.media.formatForm.getFormattedMedia(); 877 formattedMedia.options = $.extend({}, mediaFile.attributes, formattedMedia.options); 878 879 // Alert the user if a selection has yet to be made. 880 if (!formattedMedia) { 881 alert(notSelected); 882 883 return; 884 } 885 886 // Select the file. 887 onSelect(formattedMedia); 888 889 // Close the dialog. 890 $(this).dialog('close'); 891 }; 892 893 // Create a jQuery UI dialog with the given options. 894 var dialog = mediaIframe.dialog(dialogOptions); 895 896 // Allow the dialog to react to re-sizing, scrolling, etc. 897 Drupal.media.popups.sizeDialog(dialog); 898 Drupal.media.popups.resizeDialog(dialog); 899 Drupal.media.popups.scrollDialog(dialog); 900 Drupal.media.popups.overlayDisplace(dialog.parents(".ui-dialog")); 901 902 return mediaIframe; 903}; 904 905Drupal.media.popups.mediaStyleSelector.mediaBrowserOnLoad = function (e) { 906}; 907 908Drupal.media.popups.mediaStyleSelector.getDefaults = function () { 909 return { 910 src: Drupal.settings.media.styleSelectorUrl, 911 onLoad: Drupal.media.popups.mediaStyleSelector.mediaBrowserOnLoad 912 }; 913}; 914 915/** 916 * Style chooser Popup. Creates a dialog for a user to choose a media style. 917 * 918 * @param mediaFile 919 * The mediaFile you are requesting this formatting form for. 920 * @todo: should this be fid? That's actually all we need now. 921 * 922 * @param Function 923 * onSubmit Function to be called when the user chooses a media style. Takes 924 * one parameter (Object formattedMedia). 925 * 926 * @param Object 927 * options Options for the mediaStyleChooser dialog. 928 */ 929Drupal.media.popups.mediaFieldEditor = function (fid, onSelect, options) { 930 var defaults = Drupal.media.popups.mediaFieldEditor.getDefaults(); 931 932 // @todo: remove this awful hack :( 933 defaults.src = defaults.src.replace('-media_id-', fid); 934 options = $.extend({}, defaults, options); 935 936 // Create an iFrame with the iFrame URL. 937 var mediaIframe = Drupal.media.popups.getPopupIframe(options.src, 'mediaFieldEditor'); 938 939 // Attach an onLoad event. 940 mediaIframe.bind('load', options, options.onLoad); 941 942 // Create an array of Dialog options. 943 var dialogOptions = Drupal.media.popups.getDialogOptions(); 944 945 // Setup the dialog buttons. 946 var ok = Drupal.t('OK'); 947 var notSelected = Drupal.t('Very sorry, there was an unknown error embedding media.'); 948 949 dialogOptions.buttons[ok] = function () { 950 // Find the current file selection. 951 var formattedMedia = this.contentWindow.Drupal.media.formatForm.getFormattedMedia(); 952 953 // Alert the user if a selection has yet to be made. 954 if (!formattedMedia) { 955 alert(notSelected); 956 957 return; 958 } 959 960 // Select the file. 961 onSelect(formattedMedia); 962 963 // Close the dialog. 964 $(this).dialog('close'); 965 }; 966 967 // Create a jQuery UI dialog with the given options. 968 var dialog = mediaIframe.dialog(dialogOptions); 969 970 // Allow the dialog to react to re-sizing, scrolling, etc. 971 Drupal.media.popups.sizeDialog(dialog); 972 Drupal.media.popups.resizeDialog(dialog); 973 Drupal.media.popups.scrollDialog(dialog); 974 Drupal.media.popups.overlayDisplace(dialog); 975 976 return mediaIframe; 977}; 978 979Drupal.media.popups.mediaFieldEditor.mediaBrowserOnLoad = function (e) { 980 981}; 982 983Drupal.media.popups.mediaFieldEditor.getDefaults = function () { 984 return { 985 // @todo: do this for real 986 src: '/media/-media_id-/edit?render=media-popup', 987 onLoad: Drupal.media.popups.mediaFieldEditor.mediaBrowserOnLoad 988 }; 989}; 990 991/** 992 * Generic functions to both the media-browser and style selector. 993 */ 994 995/** 996 * Returns the commonly used options for the dialog. 997 */ 998Drupal.media.popups.getDialogOptions = function () { 999 return { 1000 title: Drupal.t('Media browser'), 1001 buttons: {}, 1002 dialogClass: Drupal.settings.media.dialogOptions.dialogclass, 1003 modal: Drupal.settings.media.dialogOptions.modal, 1004 draggable: Drupal.settings.media.dialogOptions.draggable, 1005 resizable: Drupal.settings.media.dialogOptions.resizable, 1006 minWidth: Drupal.settings.media.dialogOptions.minwidth, 1007 width: Drupal.settings.media.dialogOptions.width, 1008 height: Drupal.settings.media.dialogOptions.height, 1009 position: Drupal.settings.media.dialogOptions.position, 1010 overlay: { 1011 backgroundColor: Drupal.settings.media.dialogOptions.overlay.backgroundcolor, 1012 opacity: Drupal.settings.media.dialogOptions.overlay.opacity 1013 }, 1014 zIndex: Drupal.settings.media.dialogOptions.zindex, 1015 close: function (event, ui) { 1016 var elem = $(event.target); 1017 var id = elem.attr('id'); 1018 if(id == 'mediaStyleSelector') { 1019 $(this).dialog("destroy"); 1020 $('#mediaStyleSelector').remove(); 1021 } 1022 else { 1023 $(this).dialog("destroy"); 1024 $('#mediaBrowser').remove(); 1025 } 1026 } 1027 }; 1028}; 1029 1030/** 1031 * Get an iframe to serve as the dialog's contents. Common to both plugins. 1032 */ 1033Drupal.media.popups.getPopupIframe = function (src, id, options) { 1034 var defaults = {width: '100%', scrolling: 'auto'}; 1035 var options = $.extend({}, defaults, options); 1036 1037 return $('<iframe class="media-modal-frame" tabindex="0"/>') 1038 .attr('src', src) 1039 .attr('width', options.width) 1040 .attr('id', id) 1041 .attr('scrolling', options.scrolling); 1042}; 1043 1044Drupal.media.popups.overlayDisplace = function (dialog) { 1045 if (parent.window.Drupal.overlay && jQuery.isFunction(parent.window.Drupal.overlay.getDisplacement)) { 1046 var overlayDisplace = parent.window.Drupal.overlay.getDisplacement('top'); 1047 1048 if (dialog.offset().top < overlayDisplace) { 1049 dialog.css('top', overlayDisplace); 1050 } 1051 } 1052} 1053 1054/** 1055 * Size the dialog when it is first loaded and keep it centered when scrolling. 1056 * 1057 * @param jQuery dialogElement 1058 * The element which has .dialog() attached to it. 1059 */ 1060Drupal.media.popups.sizeDialog = function (dialogElement) { 1061 if (!dialogElement.is(':visible')) { 1062 return; 1063 } 1064 1065 var windowWidth = $(window).width(); 1066 var dialogWidth = windowWidth * 0.8; 1067 var windowHeight = $(window).height(); 1068 var dialogHeight = windowHeight * 0.8; 1069 1070 dialogElement.dialog("option", "width", dialogWidth); 1071 dialogElement.dialog("option", "height", dialogHeight); 1072 dialogElement.dialog("option", "position", 'center'); 1073 1074 $('.media-modal-frame').width('100%'); 1075} 1076 1077/** 1078 * Resize the dialog when the window changes. 1079 * 1080 * @param jQuery dialogElement 1081 * The element which has .dialog() attached to it. 1082 */ 1083Drupal.media.popups.resizeDialog = function (dialogElement) { 1084 $(window).resize(function() { 1085 Drupal.media.popups.sizeDialog(dialogElement); 1086 }); 1087} 1088 1089/** 1090 * Keeps the dialog centered when the window is scrolled. 1091 * 1092 * @param jQuery dialogElement 1093 * The element which has .dialog() attached to it. 1094 */ 1095Drupal.media.popups.scrollDialog = function (dialogElement) { 1096 // Keep the dialog window centered when scrolling. 1097 $(window).scroll(function() { 1098 if (!dialogElement.is(':visible')) { 1099 return; 1100 } 1101 1102 dialogElement.dialog("option", "position", 'center'); 1103 }); 1104} 1105 1106})(jQuery); 1107; 1108/** 1109 * @file 1110 * Opens the media browser then edit field 1111 */ 1112 1113(function ($) { 1114 1115/** 1116 * Attach behaviors to media element browse fields. 1117 */ 1118Drupal.behaviors.oaFilesUpload = { 1119 attach: function (context, settings) { 1120 $('a:not(.oa-files-processed)[href*="oa-files/upload"]', context).addClass('oa-files-processed').each(function() { 1121 var $link = $(this); 1122 $(this).click(function() { 1123 Drupal.media.popups.mediaBrowser(function(selected) { 1124 var browserSrc = settings.oa_files_upload_url + '/'; 1125 for (key in selected) { 1126 browserSrc += selected[key].fid + '+'; 1127 } 1128 browserSrc += '/js-return?render=oa-files-popup'; 1129 if ($link[0].search) { 1130 browserSrc += '&' + $link[0].search.substr(1); 1131 } 1132 var mediaIframe = Drupal.media.popups.getPopupIframe(browserSrc, 'oaFilesUpload'); 1133 mediaIframe.bind('load', {}, function (e) { 1134 // Return can be json or a page, want to act on the json. 1135 var parsed_json; 1136 var frame_html = $('#json-encode', this.contentWindow.document).html(); 1137 if (!frame_html) { 1138 return; 1139 } 1140 try { 1141 parsed_json = JSON.parse(frame_html) 1142 } 1143 catch(err) { 1144 return; 1145 } 1146 if (parsed_json) { 1147 for (var i in parsed_json) { 1148 if (parsed_json.hasOwnProperty(i) && parsed_json[i]['command'] && Drupal.ajax.prototype.commands[parsed_json[i]['command']]) { 1149 Drupal.ajax.prototype.commands[parsed_json[i]['command']](Drupal.ajax.prototype, parsed_json[i], 'success'); 1150 } 1151 } 1152 mediaIframe.dialog("close"); 1153 } 1154 }); 1155 var dialogOptions = Drupal.media.popups.getDialogOptions(); 1156 var dialog = mediaIframe.dialog(dialogOptions); 1157 Drupal.media.popups.sizeDialog(dialog); 1158 Drupal.media.popups.resizeDialog(dialog); 1159 Drupal.media.popups.scrollDialog(dialog); 1160 1161 }, settings.oa_files_media_options.global, {}, settings.oa_files_media_options.widget); 1162 return false;
1163 }) 1164 }); 1165 }, 1166}; 1167 1168})(jQuery); 1169 1170; 1171(function ($) { 1172 1173/** 1174 * A progressbar object. Initialized with the given id. Must be inserted into 1175 * the DOM afterwards through progressBar.element. 1176 * 1177 * method is the function which will perform the HTTP request to get the 1178 * progress bar state. Either "GET" or "POST". 1179 * 1180 * e.g. pb = new progressBar('myProgressBar'); 1181 * some_element.appendChild(pb.element); 1182 */ 1183Drupal.progressBar = function (id, updateCallback, method, errorCallback) { 1184 var pb = this; 1185 this.id = id; 1186 this.method = method || 'GET'; 1187 this.updateCallback = updateCallback; 1188 this.errorCallback = errorCallback; 1189 1190 // The WAI-ARIA setting aria-live="polite" will announce changes after users 1191 // have completed their current activity and not interrupt the screen reader. 1192 this.element = $('<div class="progress" aria-live="polite"></div>').attr('id', id); 1193 this.element.html('<div class="bar"><div class="filled"></div></div>' + 1194 '<div class="percentage"></div>' + 1195 '<div class="message"> </div>'); 1196}; 1197 1198/** 1199 * Set the percentage and status message for the progressbar. 1200 */ 1201Drupal.progressBar.prototype.setProgress = function (percentage, message) { 1202 if (percentage >= 0 && percentage <= 100) { 1203 $('div.filled', this.element).css('width', percentage + '%'); 1204 $('div.percentage', this.element).html(percentage + '%'); 1205 } 1206 $('div.message', this.element).html(message); 1207 if (this.updateCallback) { 1208 this.updateCallback(percentage, message, this); 1209 } 1210}; 1211 1212/** 1213 * Start monitoring progress via Ajax. 1214 */ 1215Drupal.progressBar.prototype.startMonitoring = function (uri, delay) { 1216 this.delay = delay; 1217 this.uri = uri; 1218 this.sendPing(); 1219}; 1220 1221/** 1222 * Stop monitoring progress via Ajax. 1223 */ 1224Drupal.progressBar.prototype.stopMonitoring = function () { 1225 clearTimeout(this.timer); 1226 // This allows monitoring to be stopped from within the callback. 1227 this.uri = null; 1228}; 1229 1230/** 1231 * Request progress data from server. 1232 */ 1233Drupal.progressBar.prototype.sendPing = function () { 1234 if (this.timer) { 1235 clearTimeout(this.timer); 1236 } 1237 if (this.uri) { 1238 var pb = this; 1239 // When doing a post request, you need non-null data. Otherwise a 1240 // HTTP 411 or HTTP 406 (with Apache mod_security) error may result. 1241 $.ajax({ 1242 type: this.method, 1243 url: this.uri, 1244 data: '', 1245 dataType: 'json', 1246 success: function (progress) { 1247 // Display errors. 1248 if (progress.status == 0) { 1249 pb.displayError(progress.data); 1250 return; 1251 } 1252 // Update display. 1253 pb.setProgress(progress.percentage, progress.message); 1254 // Schedule next timer. 1255 pb.timer = setTimeout(function () { pb.sendPing(); }, pb.delay); 1256 }, 1257 error: function (xmlhttp) { 1258 pb.displayError(Drupal.ajaxError(xmlhttp, pb.uri)); 1259 } 1260 }); 1261 } 1262}; 1263 1264/** 1265 * Display errors on the page. 1266 */ 1267Drupal.progressBar.prototype.displayError = function (string) { 1268 var error = $('<div class="messages error"></div>').html(string); 1269 $(this.element).before(error).hide(); 1270 1271 if (this.errorCallback) { 1272 this.errorCallback(this); 1273 } 1274}; 1275 1276})(jQuery); 1277; 1278/** 1279 * @file 1280 */ 1281 1282(function ($) { 1283 1284 'use strict'; 1285 1286 Drupal.extlink = Drupal.extlink || {}; 1287 1288 Drupal.extlink.attach = function (context, settings) { 1289 if (!settings.hasOwnProperty('extlink')) { 1290 return; 1291 } 1292 1293 // Strip the host name down, removing ports, subdomains, or www. 1294 var pattern = /^(([^\/:]+?\.)*)([^\.:]{1,})((\.[a-z0-9]{1,253})*)(:[0-9]{1,5})?$/; 1295 var host = window.location.host.replace(pattern, '$2$3$6'); 1296 var subdomain = window.location.host.replace(host, ''); 1297 1298 // Determine what subdomains are considered internal. 1299 var subdomains; 1300 if (settings.extlink.extSubdomains) { 1301 subdomains = '([^/]*\\.)?'; 1302 } 1303 else if (subdomain === 'www.' || subdomain === '') { 1304 subdomains = '(www\\.)?'; 1305 } 1306 else { 1307 subdomains = subdomain.replace('.', '\\.'); 1308 } 1309 1310 // Build regular expressions that define an internal link. 1311 var internal_link = new RegExp('^https?://([^@]*@)?' + subdomains + host, 'i'); 1312 1313 // Extra internal link matching. 1314 var extInclude = false;
1315 if (settings.extlink.extInclude) { 1316 extInclude = new RegExp(settings.extlink.extInclude.replace(/\\/, '\\'), 'i'); 1317 } 1318 1319 // Extra external link matching. 1320 var extExclude = false; 1321 if (settings.extlink.extExclude) { 1322 extExclude = new RegExp(settings.extlink.extExclude.replace(/\\/, '\\'), 'i'); 1323 } 1324 1325 // Extra external link CSS selector exclusion. 1326 var extCssExclude = false; 1327 if (settings.extlink.extCssExclude) { 1328 extCssExclude = settings.extlink.extCssExclude; 1329 } 1330 1331 // Extra external link CSS selector explicit. 1332 var extCssExplicit = false; 1333 if (settings.extlink.extCssExplicit) { 1334 extCssExplicit = settings.extlink.extCssExplicit; 1335 } 1336 1337 // Define the jQuery method (either 'append' or 'prepend') of placing the icon, defaults to 'append'. 1338 var extIconPlacement = settings.extlink.extIconPlacement || 'append'; 1339 1340 // Find all links which are NOT internal and begin with http as opposed 1341 // to ftp://, javascript:, etc. other kinds of links. 1342 // When operating on the 'this' variable, the host has been appended to 1343 // all links by the browser, even local ones. 1344 // In jQuery 1.1 and higher, we'd use a filter method here, but it is not 1345 // available in jQuery 1.0 (Drupal 5 default). 1346 var external_links = []; 1347 var mailto_links = []; 1348 $('a:not([data-extlink]), area:not([data-extlink])', context).each(function (el) { 1349 try { 1350 var url = ''; 1351 if (typeof this.href == 'string') { 1352 url = this.href.toLowerCase(); 1353 } 1354 // Handle SVG links (xlink:href). 1355 else if (typeof this.href == 'object') { 1356 url = this.href.baseVal; 1357 } 1358 if (url.indexOf('http') === 0 1359 && ((!url.match(internal_link) && !(extExclude && url.match(extExclude))) || (extInclude && url.match(extInclude))) 1360 && !(extCssExclude && $(this).is(extCssExclude)) 1361 && !(extCssExclude && $(this).parents(extCssExclude).length > 0) 1362 && !(extCssExplicit && $(this).parents(extCssExplicit).length < 1)) { 1363 external_links.push(this); 1364 } 1365 // Do not include area tags with begin with mailto: (this prohibits 1366 // icons from being added to image-maps). 1367 else if (this.tagName !== 'AREA' 1368 && url.indexOf('mailto:') === 0 1369 && !(extCssExclude && $(this).parents(extCssExclude).length > 0) 1370 && !(extCssExplicit && $(this).parents(extCssExplicit).length < 1)) { 1371 mailto_links.push(this); 1372 } 1373 } 1374 // IE7 throws errors often when dealing with irregular links, such as: 1375 // <a href="node/10"></a> Empty tags. 1376 // <a href="http://user:[email protected]">example</a> User:pass syntax. 1377 catch (error) { 1378 return false; 1379 } 1380 }); 1381 1382 if (settings.extlink.extClass) { 1383 Drupal.extlink.applyClassAndSpan(external_links, settings.extlink.extClass, extIconPlacement); 1384 } 1385 1386 if (settings.extlink.mailtoClass) { 1387 Drupal.extlink.applyClassAndSpan(mailto_links, settings.extlink.mailtoClass, extIconPlacement); 1388 } 1389 1390 if (settings.extlink.extTarget) { 1391 // Apply the target attribute to all links. 1392 $(external_links).attr('target', settings.extlink.extTarget); 1393 // Add rel attributes noopener and noreferrer. 1394 $(external_links).attr('rel', function (i, val) { 1395 // If no rel attribute is present, create one with the values noopener and noreferrer. 1396 if (val == null) { 1397 return 'noopener noreferrer'; 1398 } 1399 // Check to see if rel contains noopener or noreferrer. Add what doesn't exist. 1400 if (val.indexOf('noopener') > -1 || val.indexOf('noreferrer') > -1) { 1401 if (val.indexOf('noopener') === -1) { 1402 return val + ' noopener'; 1403 } 1404 if (val.indexOf('noreferrer') === -1) { 1405 return val + ' noreferrer'; 1406 } 1407 // Both noopener and noreferrer exist. Nothing needs to be added. 1408 else { 1409 return val; 1410 } 1411 } 1412 // Else, append noopener and noreferrer to val. 1413 else { 1414 return val + ' noopener noreferrer'; 1415 } 1416 }); 1417 } 1418 1419 Drupal.extlink = Drupal.extlink || {}; 1420 1421 // Set up default click function for the external links popup. This should be 1422 // overridden by modules wanting to alter the popup. 1423 Drupal.extlink.popupClickHandler = Drupal.extlink.popupClickHandler || function () { 1424 if (settings.extlink.extAlert) { 1425 return confirm(settings.extlink.extAlertText); 1426 } 1427 }; 1428 1429 $(external_links).click(function (e) { 1430 return Drupal.extlink.popupClickHandler(e, this); 1431 }); 1432 }; 1433 1434 /** 1435 * Apply a class and a trailing <span> to all links not containing images. 1436 * 1437 * @param {object[]} links 1438 * An array of DOM elements representing the links. 1439 * @param {string} class_name 1440 * The class to apply to the links. 1441 * @param {string} icon_placement 1442 * 'append' or 'prepend' the icon to the link. 1443 */ 1444 Drupal.extlink.applyClassAndSpan = function (links, class_name, icon_placement) { 1445 var $links_to_process; 1446 if (Drupal.settings.extlink.extImgClass) { 1447 $links_to_process = $(links); 1448 } 1449 else { 1450 var links_with_images = $(links).find('img').parents('a'); 1451 $links_to_process = $(links).not(links_with_images); 1452 } 1453 // Add data-extlink attribute. 1454 $links_to_process.attr('data-extlink', ''); 1455 var i; 1456 var length = $links_to_process.length; 1457 for (i = 0; i < length; i++) { 1458 var $link = $($links_to_process[i]);
1459 if ($link.css('display') === 'inline' || $link.css('display') === 'inline-block') { 1460 if (Drupal.settings.extlink.extUseFontAwesome) { 1461 if (class_name === Drupal.settings.extlink.mailtoClass) { 1462 $link[icon_placement]('<span class="fa-' + class_name + ' extlink"><span class="fa fa-envelope-o" title="' + Drupal.settings.extlink.mailtoLabel + '"></span><span class="element-invisible">' + Drupal.settings.extlink.mailtoLabel + '</span></span>'); 1463 } 1464 else { 1465 $link[icon_placement]('<span class="fa-' + class_name + ' extlink"><span class="fa fa-external-link" title="' + Drupal.settings.extlink.extLabel + '"></span><span class="element-invisible">' + Drupal.settings.extlink.extLabel + '</span></span>'); 1466 } 1467 } 1468 else { 1469 if (class_name === Drupal.settings.extlink.mailtoClass) { 1470 $link[icon_placement]('<span class="' + class_name + '"><span class="element-invisible">' + Drupal.settings.extlink.mailtoLabel + '</span></span>'); 1471 } 1472 else { 1473 $link[icon_placement]('<span class="' + class_name + '"><span class="element-invisible">' + Drupal.settings.extlink.extLabel + '</span></span>'); 1474 } 1475 } 1476 } 1477 } 1478 }; 1479 1480 Drupal.behaviors.extlink = Drupal.behaviors.extlink || {}; 1481 Drupal.behaviors.extlink.attach = function (context, settings) { 1482 // Backwards compatibility, for the benefit of modules overriding extlink 1483 // functionality by defining an "extlinkAttach" global function. 1484 if (typeof extlinkAttach === 'function') { 1485 extlinkAttach(context); 1486 } 1487 else { 1488 Drupal.extlink.attach(context, settings); 1489 } 1490 }; 1491 1492})(jQuery); 1493; 1494/** 1495 * @file Common data layer helper. 1496 */ 1497 1498(function ($) { 1499 Drupal.behaviors.dataLayer = { 1500 1501 /** 1502 * The language prefix list (no blank). 1503 * 1504 * @return {array} 1505 */ 1506 langPrefixes: function langPrefixes() { 1507 var languages = Drupal.settings.dataLayer.languages, 1508 langList = []; 1509 1510 for (var lang in languages) { 1511 if (languages[lang].prefix !== '') { 1512 langList.push(languages[lang].prefix); 1513 } 1514 } 1515 return langList; 1516 1517 // With Underscore.js dependency. 1518 //var list = _.pluck(Drupal.settings.datalayer.languages, 'prefix'); 1519 //return _.filter(list, function(lang) { return lang }); 1520 }, 1521 1522 /** 1523 * Drupal behavior. 1524 */ 1525 attach: function() { return } 1526 1527 }; 1528})(jQuery); 1529; 1530/** 1531 * @file 1532 * Manage spacing for banners in oa_appearance. 1533 */ 1534 1535(function ($) { 1536 1537 /* force the banners to be displayed within one second since 1538 poormanscron can delay this for a while 1539 */ 1540 setTimeout(function() { 1541 var $banner = $('.oa-banner'); 1542 $banner.each( function(index) { 1543 $(this).addClass('oa-banner-appeared'); 1544 }); 1545 }, 1000); 1546 1547 Drupal.behaviors.oaAppearance = { 1548 attach: function(context, settings) { 1549 var $oa_navbar = $('#oa-navbar', context); 1550 var $banner = $('.oa-banner', context); 1551 if ($oa_navbar.length && $banner.length) { 1552 var $height = $oa_navbar.height(); 1553 var $width = $oa_navbar.width(); 1554 $delta_height = 0; 1555 $banner.each( function(index) { 1556 if (!$(this).hasClass('oa-banner-appeared') && 1557 !$(this).hasClass('oa-banner-hidden')) { 1558 // set the image sizes before image gets loaded 1559 var $img_width = parseInt($(this).attr('data-width')); 1560 var $img_height = parseInt($(this).attr('data-height')); 1561 if ($img_width > 0) { 1562 // stretched banner image 1563 var $max_height = document.documentElement.clientHeight / 3; 1564 var $new_width = $new_height * $img_width / $img_height; 1565 var $new_height = Math.min( $img_height * $width / $img_width, $max_height); 1566 if ($(this).parents('#oa-navbar').length) { 1567 // this image is within the navbar 1568 $delta_height -= $(this).height(); 1569 $delta_height += $new_height; 1570 } 1571 $(this).css('height', $new_height + 'px'); 1572 $(this).css('max-height', $max_height + 'px'); 1573 $(this).addClass('oa-banner-hidden'); 1574 var $image = $('.oa-banner-overlay-img', this); 1575 if ($image.length) { 1576 $image.css('width', '100%'); 1577 } 1578 } 1579 else { 1580 // non-stretching banner image 1581 $(this).addClass('oa-banner-appeared'); 1582 } 1583 } 1584 }); 1585 } 1586 } 1587 }; 1588 1589 $(window).load(function() { 1590 var $oa_navbar = $('#oa-navbar'); 1591 var $image = $('.oa-banner-overlay-img'); 1592 var $banner = $('.oa-banner'); 1593 if ($banner.length) { 1594 $banner.each( function(index) { 1595 $(this).css( 'height', 'auto'); // let the banner resize from now on 1596 $(this).addClass('oa-banner-appeared'); 1597 $(this).removeClass('oa-banner-hidden'); 1598 }); 1599 } 1600 }); 1601 1602}(jQuery)); 1603; 1604/** 1605 * @file views_load_more.js 1606 * 1607 * Handles the AJAX pager for the view_load_more plugin. 1608 */ 1609(function ($) { 1610 1611 /** 1612 * Provide a series of commands that the server can request the client perform. 1613 */ 1614 Drupal.ajax.prototype.commands.viewsLoadMoreAppend = function (ajax, response, status) { 1615 // Get information from the response. If it is not there, default to 1616 // our presets. 1617 var wrapper = response.selector ? $(response.selector) : $(ajax.wrapper); 1618 var method = response.method || ajax.method; 1619 var targetList = response.targetList || ''; 1620 var effect = ajax.getEffect(response); 1621 var pager_selector = response.options.pager_selector ? response.options.pager_selector : '.pager-load-more'; 1622
1623 // We don't know what response.data contains: it might be a string of text 1624 // without HTML, so don't rely on jQuery correctly iterpreting 1625 // $(response.data) as new HTML rather than a CSS selector. Also, if 1626 // response.data contains top-level text nodes, they get lost with either 1627 // $(response.data) or $('<div></div>').replaceWith(response.data). 1628 var new_content_wrapped = $('<div></div>').html(response.data); 1629 var new_content = new_content_wrapped.contents(); 1630 1631 // For legacy reasons, the effects processing code assumes that new_content 1632 // consists of a single top-level element. Also, it has not been 1633 // sufficiently tested whether attachBehaviors() can be successfully called 1634 // with a context object that includes top-level text nodes. However, to 1635 // give developers full control of the HTML appearing in the page, and to 1636 // enable Ajax content to be inserted in places where DIV elements are not 1637 // allowed (e.g., within TABLE, TR, and SPAN parents), we check if the new 1638 // content satisfies the requirement of a single top-level element, and 1639 // only use the container DIV created above when it doesn't. For more 1640 // information, please see http://drupal.org/node/736066. 1641 if (new_content.length != 1 || new_content.get(0).nodeType != 1) { 1642 new_content = new_content_wrapped; 1643 } 1644 // If removing content from the wrapper, detach behaviors first. 1645 var settings = response.settings || ajax.settings || Drupal.settings; 1646 Drupal.detachBehaviors(wrapper, settings); 1647 if ($.waypoints != undefined) { 1648 $.waypoints('refresh'); 1649 } 1650 1651 // Set up our default query options. This is for advance users that might 1652 // change there views layout classes. This allows them to write there own 1653 // jquery selector to replace the content with. 1654 // Provide sensible defaults for unordered list, ordered list and table 1655 // view styles. 1656 var content_query = targetList && !response.options.content ? '> .view-content ' + targetList : response.options.content || '> .view-content'; 1657 1658 // If we're using any effects. Hide the new content before adding it to the DOM. 1659 if (effect.showEffect != 'show') { 1660 new_content.find(content_query).children().hide(); 1661 } 1662 1663 // Update the pager 1664 // Find both for the wrapper as the newly loaded content the direct child 1665 // .item-list in case of nested pagers 1666 wrapper.find(pager_selector).replaceWith(new_content.find(pager_selector)); 1667 1668 // Add the new content to the page. 1669 wrapper.find(content_query)[method](new_content.find(content_query).children()); 1670 1671 // Re-class the loaded content. 1672 // @todo this is faulty in many ways. first of which is that user may have configured view to not have these classes at all. 1673 wrapper.find(content_query).children() 1674 .removeClass('views-row-first views-row-last views-row-odd views-row-even') 1675 .filter(':first') 1676 .addClass('views-row-first') 1677 .end() 1678 .filter(':last') 1679 .addClass('views-row-last') 1680 .end() 1681 .filter(':even') 1682 .addClass('views-row-odd') 1683 .end() 1684 .filter(':odd') 1685 .addClass('views-row-even') 1686 .end(); 1687 1688 if (effect.showEffect != 'show') { 1689 wrapper.find(content_query).children(':not(:visible)')[effect.showEffect](effect.showSpeed); 1690 } 1691 1692 // Additional processing over new content 1693 wrapper.trigger('views_load_more.new_content', new_content.clone()); 1694 1695 // Attach all JavaScript behaviors to the new content 1696 // Remove the Jquery once Class, TODO: There needs to be a better 1697 // way of doing this, look at .removeOnce() :-/ 1698 var classes = wrapper.attr('class'); 1699 var onceClass = classes.match(/jquery-once-[0-9]*-[a-z]*/); 1700 wrapper.removeClass(onceClass[0]); 1701 settings = response.settings || ajax.settings || Drupal.settings; 1702 Drupal.attachBehaviors(wrapper, settings); 1703 }; 1704 1705 /** 1706 * Attaches the AJAX behavior to Views Load More waypoint support. 1707 */ 1708 Drupal.behaviors.ViewsLoadMore = { 1709 attach: function (context, settings) { 1710 var default_opts = { 1711 offset: '100%' 1712 }; 1713 1714 if (settings && settings.viewsLoadMore && settings.views && settings.views.ajaxViews) { 1715 $.each(settings.viewsLoadMore, function(i, setting) { 1716 var view = '.view-id-' + setting.view_name + '.view-display-id-' + setting.view_display_id + ' .pager-next a', 1717 opts = {}; 1718 1719 $.extend(opts, default_opts, settings.viewsLoadMore[i].opts); 1720 1721 $(view).waypoint('destroy'); 1722 $(view).waypoint(function(event, direction) { 1723 $(view).click(); 1724 }, opts); 1725 }); 1726 } 1727 }, 1728 detach: function (context, settings, trigger) { 1729 if (settings && settings.viewsLoadMore && settings.views && settings.views.ajaxViews) { 1730 $.each(settings.viewsLoadMore, function(i, setting) { 1731 var view = '.view-id-' + setting.view_name + '.view-display-id-' + setting.view_display_id; 1732 if ($(context).is(view)) { 1733 $('.pager-next a', view).waypoint('destroy'); 1734 } 1735 else { 1736 $(view, context).waypoint('destroy'); 1737 } 1738 }); 1739 } 1740 } 1741 }; 1742})(jQuery); 1743; 1744/** 1745 * @file 1746 * Manage spacing for dashboard and navbar tray. 1747 */ 1748 1749// Test for js class existence before adding. 1750if( document.documentElement.className.indexOf("js") === -1 ) { 1751 document.documentElement.className += " js"; 1752} 1753 1754(function ($) { 1755 1756 var $use_mouseover; 1757 1758 function debounce(func, wait, immediate) { 1759 var timeout; 1760 return function() { 1761 var context = this, args = arguments; 1762 var later = function() { 1763 timeout = null;
1764 if (!immediate) func.apply(context, args); 1765 }; 1766 var callNow = immediate && !timeout; 1767 clearTimeout(timeout); 1768 timeout = setTimeout(later, wait); 1769 if (callNow) func.apply(context, args); 1770 }; 1771 } 1772 1773 Drupal.behaviors.oaDashboard = { 1774 attach: function(context, settings) { 1775 // Remove Radix dropdown on hover. 1776 1777 $use_mouseover = ('oa_toolbar' in settings) ? settings.oa_toolbar.mouseover : false; 1778 1779 var $navbar = $('#navbar-bar'); 1780 if ($navbar.length) { 1781 // if using OA navbar, hide the navbar module's nav bar and remove its offset 1782 $navbar.hide(); 1783 $navbar.removeAttr('data-offset-top'); 1784 } 1785 } 1786 }; 1787 1788 function unbindMouse(selector) { 1789 $(selector).each(function () { 1790 $(this).unbind('mouseenter'); 1791 $(this).unbind('mouseleave'); 1792 $(this).unbind('focusin'); 1793 $(this).unbind('focusout'); 1794 $(this).unbind('click.oa-radix.dropdown'); 1795 if ($(this).is('.dropdown')) { 1796 var toggle = $('a.dropdown-toggle', $(this)); 1797 if ((toggle.length > 0) && (toggle.attr('href') != '')) { 1798 toggle.data('href', toggle.attr('href')); 1799 toggle.attr('href', ''); 1800 } 1801 } 1802 }); 1803 } 1804 1805 function fixMouseOverLoad() { 1806 // Always remove dropdown hover for mobile menus 1807 unbindMouse('.oa-responsive-regions-mobile.radix-dropdown-processed'); 1808 fixMouseOver(); 1809 } 1810 1811 // Helper function to show the dropdown. 1812 // These two functions taken from radix.script.js 1813 function show(dropdown) { 1814 if (!$(dropdown).hasClass('open')) { 1815 $('>[data-toggle="dropdown"]', dropdown).trigger('click.bs.dropdown'); 1816 } 1817 } 1818 1819 // Helper function to hide the dropdown. 1820 function hide(dropdown) { 1821 if ($(dropdown).hasClass('open')) { 1822 $('>[data-toggle="dropdown"]', dropdown).trigger('click.bs.dropdown'); 1823 } 1824 } 1825 1826 function fixMouseOver() { 1827 if (!$use_mouseover) { 1828 unbindMouse('.radix-dropdown-processed'); 1829 } 1830 else if ($(document).width() < 768) { 1831 unbindMouse('.radix-dropdown-processed'); 1832 } 1833 else { 1834 // Restore some mouseover on larger screens 1835 $('.radix-dropdown-processed').each(function () { 1836 if ($(this).not('.oa-responsive-regions-mobile')) { 1837 // Show dropdown on hover and focus. 1838 $(this).on('mouseenter.radix.dropdown', function(e) { 1839 show($(this)); 1840 }); 1841 $(this).on('mouseleave.radix.dropdown', function(e) { 1842 hide($(this)); 1843 }); 1844 $(this).on('click.oa-radix.dropdown', function(e) { 1845 hide($(this)); 1846 }); 1847 // Restore any links 1848 if ($(this).is('.dropdown')) { 1849 var toggle = $('a.dropdown-toggle', $(this)); 1850 if ((toggle.length > 0) && (toggle.attr('href') == '') && (toggle.data('href') != '')) { 1851 toggle.attr('href', toggle.data('href')); 1852 toggle.data('href', ''); 1853 } 1854 } 1855 } 1856 }); 1857 // Don't allow mouse-over menus in main content area 1858 unbindMouse('#main .radix-dropdown-processed'); 1859 } 1860 } 1861 1862 var updateMouseOver = debounce(function(){ 1863 fixMouseOver(); 1864 }, 250); 1865 var updateMouseOverLoad = debounce(function(){ 1866 fixMouseOverLoad(); 1867 }, 250); 1868 1869 window.addEventListener('load', updateMouseOverLoad); 1870 window.addEventListener('resize', updateMouseOver); 1871 1872}(jQuery)); 1873; 1874/** 1875 * @file 1876 * Some basic behaviors and utility functions for Views. 1877 */ 1878(function ($) { 1879 1880 Drupal.Views = {}; 1881 1882 /** 1883 * JQuery UI tabs, Views integration component. 1884 */ 1885 Drupal.behaviors.viewsTabs = { 1886 attach: function (context) { 1887 if ($.viewsUi && $.viewsUi.tabs) { 1888 $('#views-tabset').once('views-processed').viewsTabs({ 1889 selectedClass: 'active' 1890 }); 1891 } 1892 1893 $('a.views-remove-link').once('views-processed').click(function(event) { 1894 var id = $(this).attr('id').replace('views-remove-link-', ''); 1895 $('#views-row-' + id).hide(); 1896 $('#views-removed-' + id).attr('checked', true); 1897 event.preventDefault(); 1898 }); 1899 /** 1900 * Here is to handle display deletion 1901 * (checking in the hidden checkbox and hiding out the row). 1902 */ 1903 $('a.display-remove-link') 1904 .addClass('display-processed') 1905 .click(function() { 1906 var id = $(this).attr('id').replace('display-remove-link-', ''); 1907 $('#display-row-' + id).hide(); 1908 $('#display-removed-' + id).attr('checked', true); 1909 return false;
1910 }); 1911 } 1912 }; 1913 1914 /** 1915 * Helper function to parse a querystring. 1916 */ 1917 Drupal.Views.parseQueryString = function (query) { 1918 var args = {}; 1919 var pos = query.indexOf('?'); 1920 if (pos != -1) { 1921 query = query.substring(pos + 1); 1922 } 1923 var pairs = query.split('&'); 1924 for (var i in pairs) { 1925 if (typeof(pairs[i]) == 'string') { 1926 var pair = pairs[i].split('='); 1927 // Ignore the 'q' path argument, if present. 1928 if (pair[0] != 'q' && pair[1]) { 1929 args[decodeURIComponent(pair[0].replace(/\+/g, ' '))] = decodeURIComponent(pair[1].replace(/\+/g, ' ')); 1930 } 1931 } 1932 } 1933 return args; 1934 }; 1935 1936 /** 1937 * Helper function to return a view's arguments based on a path. 1938 */ 1939 Drupal.Views.parseViewArgs = function (href, viewPath) { 1940 1941 // Provide language prefix. 1942 if (Drupal.settings.pathPrefix) { 1943 var viewPath = Drupal.settings.pathPrefix + viewPath; 1944 } 1945 var returnObj = {}; 1946 var path = Drupal.Views.getPath(href); 1947 // Ensure we have a correct path. 1948 if (viewPath && path.substring(0, viewPath.length + 1) == viewPath + '/') { 1949 var args = decodeURIComponent(path.substring(viewPath.length + 1, path.length)); 1950 returnObj.view_args = args; 1951 returnObj.view_path = path; 1952 } 1953 return returnObj; 1954 }; 1955 1956 /** 1957 * Strip off the protocol plus domain from an href. 1958 */ 1959 Drupal.Views.pathPortion = function (href) { 1960 // Remove e.g. http://example.com if present. 1961 var protocol = window.location.protocol; 1962 if (href.substring(0, protocol.length) == protocol) { 1963 // 2 is the length of the '//' that normally follows the protocol. 1964 href = href.substring(href.indexOf('/', protocol.length + 2)); 1965 } 1966 return href; 1967 }; 1968 1969 /** 1970 * Return the Drupal path portion of an href. 1971 */ 1972 Drupal.Views.getPath = function (href) { 1973 href = Drupal.Views.pathPortion(href); 1974 href = href.substring(Drupal.settings.basePath.length, href.length); 1975 // 3 is the length of the '?q=' added to the url without clean urls. 1976 if (href.substring(0, 3) == '?q=') { 1977 href = href.substring(3, href.length); 1978 } 1979 var chars = ['#', '?', '&']; 1980 for (var i in chars) { 1981 if (href.indexOf(chars[i]) > -1) { 1982 href = href.substr(0, href.indexOf(chars[i])); 1983 } 1984 } 1985 return href; 1986 }; 1987 1988})(jQuery); 1989; 1990/** 1991 * @file 1992 * Handles AJAX fetching of views, including filter submission and response. 1993 */ 1994(function ($) { 1995 1996 /** 1997 * Attaches the AJAX behavior to exposed filter forms and key views links. 1998 */ 1999 Drupal.behaviors.ViewsAjaxView = {}; 2000 Drupal.behaviors.ViewsAjaxView.attach = function() { 2001 if (Drupal.settings && Drupal.settings.views && Drupal.settings.views.ajaxViews) { 2002 $.each(Drupal.settings.views.ajaxViews, function(i, settings) { 2003 Drupal.views.instances[i] = new Drupal.views.ajaxView(settings); 2004 }); 2005 } 2006 }; 2007 2008 Drupal.views = {}; 2009 Drupal.views.instances = {}; 2010 2011 /** 2012 * JavaScript object for a certain view. 2013 */ 2014 Drupal.views.ajaxView = function(settings) { 2015 var selector = '.view-dom-id-' + settings.view_dom_id; 2016 this.$view = $(selector); 2017 2018 // Retrieve the path to use for views' ajax. 2019 var ajax_path = Drupal.settings.views.ajax_path; 2020 2021 // If there are multiple views this might've ended up showing up multiple 2022 // times. 2023 if (ajax_path.constructor.toString().indexOf("Array") != -1) { 2024 ajax_path = ajax_path[0]; 2025 } 2026 2027 // Check if there are any GET parameters to send to views. 2028 var queryString = window.location.search || ''; 2029 if (queryString !== '') { 2030 // Remove the question mark and Drupal path component if any. 2031 var queryString = queryString.slice(1).replace(/q=[^&]+&?|&?render=[^&]+/, ''); 2032 if (queryString !== '') { 2033 // If there is a '?' in ajax_path, clean url are on and & should be 2034 // used to add parameters. 2035 queryString = ((/\?/.test(ajax_path)) ? '&' : '?') + queryString; 2036 } 2037 } 2038 2039 this.element_settings = { 2040 url: ajax_path + queryString, 2041 submit: settings, 2042 setClick: true, 2043 event: 'click', 2044 selector: selector, 2045 progress: { 2046 type: 'throbber' 2047 } 2048 }; 2049 2050 this.settings = settings; 2051
2052 // Add the ajax to exposed forms. 2053 this.$exposed_form = $('#views-exposed-form-' + settings.view_name.replace(/_/g, '-') + '-' + settings.view_display_id.replace(/_/g, '-') + '-' + settings.view_dom_id); 2054 this.$exposed_form.once(jQuery.proxy(this.attachExposedFormAjax, this)); 2055 2056 // Store Drupal.ajax objects here for all pager links. 2057 this.links = []; 2058 2059 // Add the ajax to pagers. 2060 this.$view 2061 .once(jQuery.proxy(this.attachPagerAjax, this)); 2062 2063 // Add a trigger to update this view specifically. In order to trigger a 2064 // refresh use the following code. 2065 // 2066 // @code 2067 // jQuery('.view-name').trigger('RefreshView'); 2068 // @endcode 2069 // Add a trigger to update this view specifically. 2070 var self_settings = this.element_settings; 2071 self_settings.event = 'RefreshView'; 2072 var self = this; 2073 this.$view.once('refresh', function () { 2074 self.refreshViewAjax = new Drupal.ajax(self.selector, self.$view, self_settings); 2075 }); 2076 }; 2077 2078 Drupal.views.ajaxView.prototype.attachExposedFormAjax = function() { 2079 var button = $('input[type=submit], button[type=submit], input[type=image]', this.$exposed_form); 2080 button = button[0]; 2081 2082 // Call the autocomplete submit before doing AJAX. 2083 $(button).click(function () { 2084 if (Drupal.autocompleteSubmit) { 2085 Drupal.autocompleteSubmit(); 2086 } 2087 }); 2088 2089 this.exposedFormAjax = new Drupal.ajax($(button).attr('id'), button, this.element_settings); 2090 }; 2091 2092 /** 2093 * Attach the ajax behavior to each link. 2094 */ 2095 Drupal.views.ajaxView.prototype.attachPagerAjax = function() { 2096 this.$view.find('ul.pager > li > a, ol.pager > li > a, th.views-field a, .attachment .views-summary a') 2097 .each(jQuery.proxy(this.attachPagerLinkAjax, this)); 2098 }; 2099 2100 /** 2101 * Attach the ajax behavior to a single link. 2102 */ 2103 Drupal.views.ajaxView.prototype.attachPagerLinkAjax = function(id, link) { 2104 var $link = $(link); 2105 var viewData = {}; 2106 var href = $link.attr('href'); 2107 // Don't attach to pagers inside nested views. 2108 if ($link.closest('.view')[0] !== this.$view[0] && 2109 $link.closest('.view').parent().hasClass('attachment') === false) { 2110 return; 2111 } 2112 2113 // Provide a default page if none has been set. This must be done 2114 // prior to merging with settings to avoid accidentally using the 2115 // page landed on instead of page 1. 2116 if (typeof(viewData.page) === 'undefined') { 2117 viewData.page = 0; 2118 } 2119 2120 // Construct an object using the settings defaults and then overriding 2121 // with data specific to the link. 2122 $.extend( 2123 viewData, 2124 this.settings, 2125 Drupal.Views.parseQueryString(href), 2126 // Extract argument data from the URL. 2127 Drupal.Views.parseViewArgs(href, this.settings.view_base_path) 2128 ); 2129 2130 // For anchor tags, these will go to the target of the anchor rather 2131 // than the usual location. 2132 $.extend(viewData, Drupal.Views.parseViewArgs(href, this.settings.view_base_path)); 2133 2134 this.element_settings.submit = viewData; 2135 this.pagerAjax = new Drupal.ajax(false, $link, this.element_settings); 2136 this.links.push(this.pagerAjax); 2137 }; 2138 2139 Drupal.ajax.prototype.commands.viewsScrollTop = function (ajax, response, status) { 2140 // Scroll to the top of the view. This will allow users 2141 // to browse newly loaded content after e.g. clicking a pager 2142 // link. 2143 var offset = $(response.selector).offset(); 2144 // We can't guarantee that the scrollable object should be 2145 // the body, as the view could be embedded in something 2146 // more complex such as a modal popup. Recurse up the DOM 2147 // and scroll the first element that has a non-zero top. 2148 var scrollTarget = response.selector; 2149 while ($(scrollTarget).scrollTop() == 0 && $(scrollTarget).parent()) { 2150 scrollTarget = $(scrollTarget).parent(); 2151 } 2152 // Only scroll upward. 2153 if (offset.top - 10 < $(scrollTarget).scrollTop()) { 2154 $(scrollTarget).animate({scrollTop: (offset.top - 10)}, 500); 2155 } 2156 }; 2157 2158})(jQuery); 2159;
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.