1(function ($) { 2 3Drupal.behaviors.popup = { 4 5 attach: function(context){ 6 7 // Make sure we have an overlay space 8 if(!$('#popup-active-overlay').length){ 9 $('body').append('<div id="popup-active-overlay"></div>'); 10 } 11 12 // Process flat menu containers 13 $('.popup-menu-flat:not(.popup-menu-flat-processed)').each( 14 function(){ 15 var thisObject = $(this); 16 thisObject.addClass('popup-menu-flat-processed'); 17 new PopupMenuContainerElement(thisObject); 18 } 19 ); 20 21 // Process popup-elements 22 $('.popup-element:not(.popup-element-processed)').each( 23 function(){ 24 var thisObject = $(this); 25 thisObject 26 .addClass('popup-element-processed') 27 .removeClass('popup-element-noscript'); 28 new PopupElement(thisObject); 29 } 30 ); 31 32 // Process menu leaves 33 $('.popup-menu-leaf-title:not(.popup-menu-leaf-processed)').each( 34 function(){ 35 var thisObject = $(this); 36 thisObject.addClass('popup-menu-leaf-processed'); 37 new PopupMenuLeafElement(thisObject); 38 } 39 ); 40 41 // Process relative links in AJAX loaded content 42 $("a[href^='/ahah/popup/view']", context).each( 43 function(){ 44 45 var thisObject = $(this); 46 var thisContext = $(thisObject.parents('div.inner').get(0)); 47 48 var placeContent = function(data){ 49 thisContext.html(data); 50 Drupal.attachBehaviors(context); 51 } 52 53 var fetchContent = function(){ 54 $.get(thisObject.attr('href'), null, placeContent); 55 return false; 56 } 57 58 thisObject.click(fetchContent); 59 } 60 ); 61 62 // Correct relative form submits 63 $(".ajax form").each( 64 function(){ 65 var thisForm = $(this); 66 67 if (thisForm.attr('action').match(/^\/ahah\/popup/)){ 68 thisForm.attr('action', ''); 69 } 70 } 71 ); 72 73 // Reposition on window resize 74 var reposition = function(){ 75 $('.popup-element').trigger('reposition'); 76 } 77 $(window).unbind('resize', reposition).resize(reposition); 78 79 } 80 81} 82 83 84 85/* ---- Popup element objects ---- */ 86 87 88 89PopupElement = function(element){ 90 91 var thisObject = this; 92 93 // Gather elements 94 this.element = element; 95 this.title = $($('.popup-element-title', this.element)[0]); 96 this.body = $($('.popup-element-body', this.element)[0]); 97 this.elementId = this.element.attr('id'); 98 this.closeButton = $('.popup-close', this.body); 99 100 this.children = new Array(); 101 102 this.isRoot = this 103 .title 104 .parents('.popup-element-body,.popup-menu-flat') 105 .length == 0; 106 107 this.body.data('popupElement', this); 108 109 // Assign show/hide effects 110 PopupElement.assignEffects.apply(this); 111 112 // Assign origin positioning function 113 PopupElement.assignPositioning.apply(this); 114 115 // Move body and add a wrapper 116 PopupElement.dom.apply(this); 117 118 // Assign expansion function 119 PopupElement.assignExpansion.apply(this); 120 121 // Assign activation/deactivation events 122 PopupElement.assignEvents.apply(this); 123 124 // Apply css attributes 125 PopupElement.applyAttributes.apply(this); 126 127 // Attach AJAX behaviors 128 PopupElement.applyAJAX.apply(this); 129 130 // Reposition on window resize 131 this.element.bind( 132 'reposition', 133 function(){ 134 thisObject.position(); 135 } 136 ); 137 138 // Close button 139 this.closeButton.click( 140 function(){ 141 PopupElement.hide.apply(thisObject); 142 return false; 143 } 144 ); 145 146} 147 148 149 150PopupMenuLeafElement = function(element){ 151 152 this.element = element; 153 this.parent = this.element.parents('.popup-element-body,.popup-menu-flat').data('popupElement'); 154 var thisObject = this; 155 156 this.element.mouseover( 157 function(){ 158 if (thisObject.parent){ 159 for(var i in thisObject.parent.children){ 160 PopupElement.hide.apply(thisObject.parent.children[i]); 161 } 162 } 163 } 164 ); 165} 166 167 168 169PopupMenuContainerElement = function(element){ 170 171 this.element = element; 172 this.body = element; 173 this.children = new Array(); 174 this.element.data('popupElement', this); 175 176} 177 178 179 180PopupElement.count = 0; 181 182 183 184/* ---- DOM preparation ---- */ 185 186 187 188PopupElement.dom = function(){ 189 190 this.body.appendTo('#popup-active-overlay'); 191 192 var classAttr = this.element.attr('class'); 193 var styleClass = classAttr.match(/popup-style-[^'\s]+/); 194 195 this.body.wrap( 196 '<div id="' + 197 this.elementId + 198 '-active" class="popup-element-wrapper' + (styleClass ? ' ' + styleClass : '') + '">' 199 ); 200 201 this.wrapper = this.body.parent(); 202 this.wrapper.css('position', 'absolute'); 203 204 // Wrap in origin element 205 this.body.wrap('<div class="popup-element-origin">'); 206 this.origin = this.body.parent(); 207 this.origin.css('position', 'absolute'); 208} 209 210 211 212/* ---- Dynamic functions ---- */ 213 214 215 216PopupElement.assignEffects = function(){ 217 var effectName = this 218 .element 219 .attr('class') 220 .match(/effect-([^\s]+)/)[1]; 221 this.animShow = new Function( 222 Drupal.settings.popup.effects.show[effectName] 223 ); 224 this.animHide = new Function( 225 Drupal.settings.popup.effects.hide[effectName] 226 ); 227} 228 229 230 231PopupElement.assignPositioning = function(){ 232 var originName = this 233 .element 234 .attr('class') 235 .match(/origin-([^\s]+)/)[1]; 236 this.position = PopupElement.position[originName]; 237} 238 239 240 241PopupElement.assignExpansion = function(){ 242 var expandName = this 243 .element 244 .attr('class') 245 .match(/expand-([^\s]+)/)[1]; 246 PopupElement.expand[expandName].apply(this); 247} 248 249 250 251PopupElement.assignEvents = function(){ 252 if (this.element.hasClass('activate-hover')){ 253 PopupElement.hoverEvents.apply(this); 254 } else { 255 PopupElement.clickEvents.apply(this); 256 } 257 258 var thisObject = this; 259 260 // API show/hide events 261 this.element.bind( 262 'hide', 263 function(){ 264 PopupElement.hide.apply(thisObject); 265 } 266 ).bind( 267 'show', 268 function(){ 269 PopupElement.show.apply(thisObject); 270 } 271 ); 272 273} 274 275 276 277PopupElement.applyAttributes = function(){ 278 279 if (this.body.attr('class')){ 280 281 var opacity = this.body.attr('class').match(/opacity-([^\s]+)/); 282 if (opacity && opacity[1] < 1){ 283 this.body.css( 284 { 285 opacity: opacity[1], 286 filter: 'alpha(opacity=' + opacity[1] + ')' 287 } 288 ); 289 } 290 291 var width = this.body.attr('class').match(/width-([^\s]+)/); 292 if (width){ 293 $('.inner', this.body).css('width', width[1] + 'px'); 294 } 295 } 296} 297 298 299 300/* ---- AJAX preparation ---- */ 301 302 303 304PopupElement.applyAJAX = function(){ 305 306 var thisObject = this; 307 308 var placeContent = function(data, destination){ 309 310 thisObject.body.unbind('showing', fetchContent); 311 var close = $('.popup-close-button', destination); 312 313 if (close.length){ 314 close.siblings().remove(); 315 destination.append(data); 316 } else { 317 destination.html(data); 318 } 319 320 Drupal.attachBehaviors(destination); 321 } 322 323 var fetchContent = function(){ 324 325 var placeHolder = thisObject.body.find('.popup-ahah-placeholder'); 326 var destination = placeHolder.parent(); 327 var url = $('a.ahah-path', placeHolder).attr('href'); 328 329 $.get(url, null, function(data){ placeContent(data, destination); }); 330 } 331 332 // Ajax 333 if (this.body.hasClass('ajax')){ 334 this.body.bind('showing', fetchContent); 335 } 336 337} 338 339 340 341/* ---- Popup actions ---- */ 342 343 344 345PopupElement.hide = function(){ 346 if (this.visible){ 347 this.body.trigger('hiding'); 348 this.animHide(); 349 this.title.removeClass('popup-title-active'); 350 this.element.removeClass('popup-element-active'); 351 this.visible = false;
352 this.body.queue('function(){ PopupElement.count--; }'); 353 this.body.trigger('hidden'); 354 } 355} 356 357 358 359PopupElement.show = function(){ 360 if (!this.visible){ 361 this.body.css('z-index', ++PopupElement.count); 362 this.body.trigger('showing'); 363 this.position(); 364 this.animShow(); 365 this.title.addClass('popup-title-active'); 366 this.element.addClass('popup-element-active'); 367 this.visible = true; 368 this.body.trigger('shown'); 369 } 370} 371 372 373 374/* ---- Popup events ---- */ 375 376 377 378PopupElement.clickEvents = function(){ 379 380 this.visible = false; 381 var thisObject = this; 382 383 this.title.click( 384 function(){ 385 if (thisObject.visible == true){ 386 PopupElement.hide.apply(thisObject); 387 } else { 388 PopupElement.show.apply(thisObject); 389 } 390 return false; 391 } 392 ); 393} 394 395 396 397PopupElement.hoverEvents = function(){ 398 399 var thisObject = this; 400 401 if (!this.isRoot){ 402 var popupElement = this.title.parents('.popup-element-body').data('popupElement'); 403 this.parent = popupElement 404 ? popupElement 405 : this.title.parents('.popup-menu-flat').data('popupElement'); 406 this.parent.children.push(this); 407 } 408 409 // Trigger hiding 410 var delayedHide = function(){ 411 clearTimeout(thisObject.hideTimeout); 412 if (thisObject.showTimeout) { 413 clearTimeout(thisObject.showTimeout); 414 } 415 thisObject.hideTimeout = setTimeout( 416 function(){ 417 PopupElement.hide.apply(thisObject); 418 }, 419 Drupal.settings.popup.linger 420 ); 421 if (!thisObject.isRoot){ 422 thisObject.parent.body.trigger('mouseleave'); 423 } 424 } 425 this.body.bind('mouseleave', delayedHide); 426 this.title.bind('mouseleave', delayedHide); 427 428 // Cancel hiding 429 var cancelHide = function(){ 430 var element = thisObject; 431 clearTimeout(thisObject.hideTimeout); 432 while(element = element.parent){ 433 clearTimeout(element.hideTimeout); 434 } 435 } 436 this.body.bind('mouseover', cancelHide); 437 this.title.bind('mouseover', cancelHide); 438 439 // Trigger showing 440 var handler = function(event){ 441 thisObject.showTimeout = setTimeout( 442 function(){ 443 if (!thisObject.visible){ 444 PopupElement.show.apply(thisObject); 445 if (thisObject.parent){ 446 for(var i in thisObject.parent.children){ 447 if (thisObject.parent.children[i] != thisObject){ 448 PopupElement.hide.apply(thisObject.parent.children[i]); 449 } 450 } 451 } 452 } 453 }, Drupal.settings.popup.delay 454 ); 455 } 456 457 this.title.bind('mouseenter', handler); 458} 459 460 461 462/* ---- Popup positioning ---- */ 463 464 465 466PopupElement.position = { 467 468 'top-left': function(){ 469 var origin = this.title.offset(); 470 this.origin.css( 471 { 472 top: origin.top, 473 left: origin.left 474 } 475 ); 476 }, 477 478 'top-right': function(){ 479 var origin = this.title.offset(); 480 this.origin.css( 481 { 482 top: origin.top, 483 left: origin.left + this.title.outerWidth() 484 } 485 ); 486 }, 487 488 'bottom-left': function(){ 489 var origin = this.title.offset(); 490 this.origin.css( 491 { 492 top: origin.top + this.title.outerHeight(), 493 left: origin.left 494 } 495 ); 496 }, 497 498 'bottom-right': function(){ 499 var origin = this.title.offset(); 500 this.origin.css( 501 { 502 top: origin.top + this.title.outerHeight(), 503 left: origin.left + this.title.outerWidth() 504 } 505 ); 506 } 507 508} 509 510 511 512PopupElement.expand = { 513 514 'top-left': function(){ 515 this.body.css({bottom: 0, right: 0}); 516 }, 517 518 'top-right': function(){ 519 this.body.css({bottom: 0, left: 0}); 520 }, 521 522 'bottom-left': function(){ 523 this.body.css({top: 0, right: 0}); 524 }, 525 526 'bottom-right': function(){ 527 this.body.css({top: 0, left: 0}); 528 } 529 530} 531 532 533})(jQuery);
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.