| [ Index ] |
PHP Cross Reference of Drupal 6 (gatewave) |
[Summary view] [Print] [Text view]
1 // $Id: display_editor.js,v 1.4.4.9 2010/08/20 16:20:44 merlinofchaos Exp $ 2 /** 3 * @file display_editor.js 4 * 5 * Contains the javascript for the Panels display editor. 6 */ 7 8 (function ($) { 9 /** Delete pane button **/ 10 Drupal.Panels.bindClickDelete = function(context) { 11 $('a.pane-delete:not(.pane-delete-processed)', context) 12 .addClass('pane-delete-processed') 13 .click(function() { 14 if (confirm('Remove this pane?')) { 15 var id = '#' + $(this).attr('id').replace('pane-delete-', ''); 16 $(id).remove(); 17 Drupal.Panels.Draggable.savePositions(); 18 } 19 return false; 20 }); 21 }; 22 23 Drupal.Panels.bindPortlet = function() { 24 var handle = $(this).find('.panel-pane-collapsible > div.pane-title'); 25 var content = $(this).find('.panel-pane-collapsible > div.pane-content'); 26 if (content.length) { 27 var toggle = $('<span class="toggle toggle-collapsed"></span>'); 28 handle.before(toggle); 29 toggle.click(function() { 30 content.slideToggle(20); 31 toggle.toggleClass('toggle-collapsed'); 32 }); 33 handle.click(function() { 34 content.slideToggle(20); 35 toggle.toggleClass('toggle-collapsed'); 36 }); 37 content.hide(); 38 } 39 }; 40 41 Drupal.Panels.Draggable = { 42 // The draggable object 43 object: null, 44 45 // Where objects can be dropped 46 dropzones: [], 47 current_dropzone: null, 48 49 // positions within dropzones where an object can be plazed 50 landing_pads: [], 51 current_pad: null, 52 53 // Where the object is 54 mouseOffset: { x: 0, y: 0 }, 55 windowOffset: { x: 0, y: 0 }, 56 offsetDivHeight: 0, 57 58 // original settings to be restored 59 original: {}, 60 // a placeholder so that if the object is let go but not over a drop zone, 61 // it can be put back where it belongs 62 placeholder: {}, 63 64 hoverclass: 'hoverclass', 65 helperclass: 'helperclass', 66 accept: 'div.panels-display', 67 handle: 'div.grabber', 68 draggable: 'div.panel-portlet', 69 main: 'div#panels-dnd-main', 70 71 // part of the id to remove to get just the number 72 draggableId: 'panel-pane-', 73 // What to add to the front of a the id to get the form id for a panel 74 formId: 'input#edit-', 75 76 maxWidth: 250, 77 78 unsetDropZone: function() { 79 $(this.current_dropzone.obj).removeClass(this.hoverclass); 80 this.current_dropzone = null; 81 for (var i in this.landing_pads) { 82 $(this.landing_pads[i].obj).remove(); 83 } 84 this.landing_pads = []; 85 this.current_pad = null; 86 }, 87 88 createLandingPad: function(where, append) { 89 var obj = $('<div class="' + this.helperclass +'" id="' + 90 $(where).attr('id') + '-dropzone"> </div>'); 91 if (append) { 92 $(where).append(obj); 93 } 94 else { 95 $(where).before(obj); 96 } 97 var offset = $(obj).offset(); 98 99 $(obj).css({ 100 display: 'none' 101 }); 102 this.landing_pads.push({ 103 centerX: offset.left + ($(obj).innerWidth() / 2), 104 centerY: offset.top + ($(obj).innerHeight() / 2), 105 obj: obj 106 }); 107 return obj; 108 }, 109 110 calculateDropZones: function(event, dropzone) { 111 var dropzones = []; 112 $(this.accept).each(function() { 113 var offset = $(this).offset({padding:true}); 114 offset.obj = this; 115 offset.width = $(this).outerWidth(); 116 offset.height = $(this).outerHeight(); 117 dropzones.push(offset); 118 }); 119 this.dropzones = dropzones; 120 }, 121 122 reCalculateDropZones: function() { 123 for (var i in this.dropzones) { 124 offset = $(this.dropzones[i].obj).offset({padding:true}); 125 offset.width = $(this.dropzones[i].obj).outerWidth(); 126 offset.height = $(this.dropzones[i].obj).outerHeight(); 127 $.extend(this.dropzones[i], offset); 128 } 129 }, 130 131 changeDropZone: function(new_dropzone) { 132 // Unset our old dropzone. 133 if (this.current_dropzone) { 134 this.unsetDropZone(); 135 } 136 137 // Set up our new dropzone. 138 this.current_dropzone = new_dropzone; 139 $(this.current_dropzone.obj).addClass(this.hoverclass); 140 // add a landing pad 141 this.createLandingPad(this.current_dropzone.obj, true); 142 143 var that = this; 144 // Create a landing pad before each existing portlet. 145 $(this.current_dropzone.obj).find(this.draggable).each(function() { 146 if (that.object.id != this.id) { 147 that.createLandingPad(this, false); 148 } 149 }); 150 }, 151 152 findLandingPad: function(x, y) { 153 var shortest_distance = null; 154 var nearest_pad = null; 155 // find the nearest pad. 156 for (var i in this.landing_pads) { 157 // This isn't the real distance, this is the square of the 158 // distance -- no point in spending processing time on 159 // sqrt. 160 var dstx = Math.abs(x - this.landing_pads[i].centerX); 161 var dsty = Math.abs(y - this.landing_pads[i].centerY); 162 var distance = (dstx * dstx) + (dsty * dsty); 163 if (shortest_distance == null || distance < shortest_distance) { 164 shortest_distance = distance; 165 nearest_pad = this.landing_pads[i]; 166 } 167 } 168 if (nearest_pad != this.current_pad) { 169 if (this.current_pad) { 170 $(this.current_pad.obj).hide(); 171 } 172 this.current_pad = nearest_pad; 173 $(nearest_pad.obj).show(); 174 } 175 }, 176 177 findDropZone: function(x, y) { 178 // Go through our dropzones and see if we're over one. 179 var new_dropzone = null; 180 for (var i in this.dropzones) { 181 // console.log('x:' + x + ' left:' + this.dropzones[i].left + ' right: ' + this.dropzones[i].left + this.dropzones[i].width); 182 if (this.dropzones[i].left < x && 183 x < this.dropzones[i].left + this.dropzones[i].width && 184 this.dropzones[i].top < y && 185 y < this.dropzones[i].top + this.dropzones[i].height) { 186 new_dropzone = this.dropzones[i]; 187 break; 188 } 189 } 190 // If we're over one, see if it's different. 191 if (new_dropzone) { 192 var changed = false; 193 if (!this.current_dropzone || new_dropzone.obj.id != this.current_dropzone.obj.id) { 194 this.changeDropZone(new_dropzone); 195 changed = true; 196 } 197 this.findLandingPad(x, y); 198 if (changed) { 199 // recalculate the size of our drop zones due to the fact that we're drawing landing pads. 200 this.reCalculateDropZones(); 201 } 202 } 203 // If we're not over one, be sure to unhilite one if we were just 204 // over it. 205 else if (this.current_dropzone) { 206 this.unsetDropZone(); 207 } 208 }, 209 210 /** save button clicked, or pane deleted **/ 211 savePositions: function() { 212 var draggable = Drupal.Panels.Draggable; 213 $(draggable.accept).each(function() { 214 var val = ''; 215 $(this).find(draggable.draggable).each(function() { 216 if (val) { 217 val += ','; 218 } 219 220 val += this.id.replace(draggable.draggableId, ''); 221 }); 222 // Note: _ is replaced with - because Drupal automatically does this 223 // with form ids. 224 $(draggable.formId + this.id.replace(/_/g, '-')).val(val); 225 }); 226 return false; 227 } 228 }; 229 230 Drupal.Panels.DraggableHandler = function() { 231 $(this).addClass('panel-draggable'); 232 var draggable = Drupal.Panels.Draggable; 233 var scrollBuffer = 10; 234 var scrollDistance = 10; 235 var scrollTimer = 30; 236 237 getMouseOffset = function(docPos, mousePos, windowPos) { 238 return { x: mousePos.x - docPos.x + windowPos.x, y: mousePos.y - docPos.y + windowPos.y}; 239 }; 240 241 getMousePos = function(ev) { 242 ev = ev || window.event; 243 244 if (ev.pageX || ev.pageY) { 245 return { x:ev.pageX, y:ev.pageY }; 246 } 247 return { 248 x:ev.clientX + document.body.scrollLeft - document.body.clientLeft, 249 y:ev.clientY + document.body.scrollTop - document.body.clientTop 250 }; 251 }; 252 253 getPosition = function(e) { 254 /* 255 if (document.defaultView && document.defaultView.getComputedStyle) { 256 var css = document.defaultView.getComputedStyle(e, null); 257 return { 258 x: parseInt(css.getPropertyValue('left')), 259 y: parseInt(css.getPropertyValue('top')) 260 }; 261 } 262 */ 263 var left = 0; 264 var top = 0; 265 266 while (e.offsetParent) { 267 left += e.offsetLeft; 268 top += e.offsetTop; 269 e = e.offsetParent; 270 } 271 272 left += e.offsetLeft; 273 top += e.offsetTop; 274 275 return { x:left, y:top }; 276 }; 277 278 mouseUp = function(e) { 279 clearTimeout(draggable.timeoutId); 280 draggable.dropzones = []; 281 282 if (draggable.current_pad) { 283 // Drop the object where we're hovering 284 $(draggable.object).insertAfter($(draggable.current_pad.obj)); 285 Drupal.Panels.changed($(draggable.object)); 286 } 287 else { 288 // or put it back where it came from 289 $(draggable.object).insertAfter(draggable.placeholder); 290 } 291 // remove the placeholder 292 draggable.placeholder.remove(); 293 294 // restore original settings. 295 $(draggable.object).css(draggable.original); 296 if (draggable.current_dropzone) { 297 draggable.unsetDropZone(); 298 } 299 300 $(document).unbind('mouseup').unbind('mousemove'); 301 draggable.savePositions(); 302 }; 303 304 mouseMove = function(e) { 305 draggable.mousePos = getMousePos(e); 306 307 draggable.findDropZone(draggable.mousePos.x, draggable.mousePos.y); 308 309 var windowMoved = parseInt(draggable.offsetDivHeight - $(draggable.main).innerHeight()); 310 311 draggable.object.style.top = draggable.mousePos.y - draggable.mouseOffset.y + windowMoved + 'px'; 312 draggable.object.style.left = draggable.mousePos.x - draggable.mouseOffset.x + 'px'; 313 $(draggable.object).toggleClass('moving'); 314 }; 315 316 mouseDown = function(e) { 317 // If we mouse-downed over something clickable, don't drag! 318 if (e.target.nodeName == 'A' || e.target.nodeName == 'INPUT' || e.target.parentNode.nodeName == 'A' || e.target.nodeName.nodeName == 'INPUT') { 319 return; 320 } 321 322 draggable.object = $(this).parent(draggable.draggable).get(0); 323 324 // create a placeholder so we can put this object back if dropped in an invalid location. 325 draggable.placeholder = $('<div class="draggable-placeholder-object" style="display:none"></div>"'); 326 $(draggable.object).after(draggable.placeholder); 327 328 // Store original CSS so we can put it back. 329 draggable.original = { 330 position: $(draggable.object).css('position'), 331 width: 'auto', 332 left: $(draggable.object).css('left'), 333 top: $(draggable.object).css('top'), 334 'z-index': $(draggable.object).css('z-index'), 335 'margin-bottom': $(draggable.object).css('margin-bottom'), 336 'margin-top': $(draggable.object).css('margin-top'), 337 'margin-left': $(draggable.object).css('margin-left'), 338 'margin-right': $(draggable.object).css('margin-right'), 339 'padding-bottom': $(draggable.object).css('padding-bottom'), 340 'padding-top': $(draggable.object).css('padding-top'), 341 'padding-left': $(draggable.object).css('padding-left'), 342 'padding-right': $(draggable.object).css('padding-right') 343 }; 344 345 draggable.mousePos = getMousePos(e); 346 var originalPos = $(draggable.object).offset(); 347 var width = Math.min($(draggable.object).innerWidth(), draggable.maxWidth); 348 349 draggable.offsetDivHeight = $(draggable.main).innerHeight(); 350 draggable.findDropZone(draggable.mousePos.x, draggable.mousePos.y); 351 352 // Make copies of these because in FF3, they actually change when we 353 // move the item, whereas they did not in FF2. 354 355 if (e.layerX || e.layerY) { 356 var layerX = e.layerX; 357 var layerY = e.layerY; 358 } 359 else if (e.originalEvent && e.originalEvent.layerX) { 360 var layerX = e.originalEvent.layerX; 361 var layerY = e.originalEvent.layerY; 362 } 363 364 // Make the draggable relative, get it out of the way and make it 365 // invisible. 366 $(draggable.object).css({ 367 position: 'relative', 368 'z-index': 100, 369 width: width + 'px', 370 'margin-bottom': (-1 * parseInt($(draggable.object).outerHeight())) + 'px', 371 'margin-top': 0, 372 'margin-left': 0, 373 'margin-right': (-1 * parseInt($(draggable.object).outerWidth())) + 'px', 374 'padding-bottom': 0, 375 'padding-top': 0, 376 'padding-left': 0, 377 'padding-right': 0, 378 'left': 0, 379 'top': 0 380 }) 381 .insertAfter($(draggable.main)); 382 var newPos = $(draggable.object).offset(); 383 384 var windowOffset = { left: originalPos.left - newPos.left, top: originalPos.top - newPos.top } 385 386 // if they grabbed outside the area where we make the draggable smaller, move it 387 // closer to the cursor. 388 if (layerX != 'undefined' && layerX > width) { 389 windowOffset.left += layerX - 10; 390 } 391 else if (layerX != 'undefined' && e.offsetX > width) { 392 windowOffset.left += e.offsetX - 10; 393 } 394 395 // This is stored so we can move with it. 396 draggable.mouseOffset = { x: draggable.mousePos.x - windowOffset.left, y: draggable.mousePos.y - windowOffset.top}; 397 draggable.offsetDivHeight = $(draggable.main).innerHeight(); 398 399 draggable.object.style.top = windowOffset.top + 'px'; 400 draggable.object.style.left = windowOffset.left + 'px'; 401 $(document).unbind('mouseup').unbind('mousemove').mouseup(mouseUp).mousemove(mouseMove); 402 403 draggable.calculateDropZones(draggable.mousePos, e); 404 draggable.timeoutId = setTimeout('timer()', scrollTimer); 405 return false; 406 }; 407 408 timer = function() { 409 if (!draggable.timeCount) { 410 draggable.timeCount = 0; 411 } 412 draggable.timeCount = draggable.timeCount + 1; 413 var left = $(window).scrollLeft(); 414 var right = left + $(window).width(); 415 var top = $(window).scrollTop(); 416 var bottom = top + $(window).height(); 417 418 if (draggable.mousePos.x < left + scrollBuffer && left > 0) { 419 window.scrollTo(left - scrollDistance, top); 420 draggable.mousePos.x -= scrollDistance; 421 draggable.object.style.top = draggable.mousePos.y - draggable.mouseOffset.y + 'px'; 422 } 423 else if (draggable.mousePos.x > right - scrollBuffer) { 424 window.scrollTo(left + scrollDistance, top); 425 draggable.mousePos.x += scrollDistance; 426 draggable.object.style.top = draggable.mousePos.y - draggable.mouseOffset.y + 'px'; 427 } 428 else if (draggable.mousePos.y < top + scrollBuffer && top > 0) { 429 window.scrollTo(left, top - scrollDistance); 430 draggable.mousePos.y -= scrollDistance; 431 draggable.object.style.top = draggable.mousePos.y - draggable.mouseOffset.y + 'px'; 432 } 433 else if (draggable.mousePos.y > bottom - scrollBuffer) { 434 window.scrollTo(left, top + scrollDistance); 435 draggable.mousePos.y += scrollDistance; 436 draggable.object.style.top = draggable.mousePos.y - draggable.mouseOffset.y + 'px'; 437 } 438 439 draggable.timeoutId = setTimeout('timer()', scrollTimer); 440 } 441 442 $(this).mousedown(mouseDown); 443 }; 444 445 $.fn.extend({ 446 panelsDraggable: Drupal.Panels.DraggableHandler 447 }); 448 449 /** 450 * Implement Drupal behavior for autoattach 451 */ 452 Drupal.behaviors.PanelsDisplayEditor = function(context) { 453 // Show javascript only items. 454 $('span#panels-js-only').css('display', 'inline'); 455 456 $('#panels-dnd-main div.panel-pane:not(.panel-portlet)') 457 .addClass('panel-portlet') 458 .each(Drupal.Panels.bindPortlet); 459 460 // The above doesn't work if context IS the pane, so do this to catch that. 461 if ($(context).hasClass('panel-pane') && !$(context).hasClass('panel-portlet')) { 462 $(context) 463 .addClass('panel-portlet') 464 .each(Drupal.Panels.bindPortlet); 465 } 466 467 // Make draggables and make sure their positions are saved. 468 $(context).find('div.grabber:not(.panel-draggable)').panelsDraggable(); 469 Drupal.Panels.Draggable.savePositions(); 470 471 // Bind buttons. 472 $('input#panels-hide-all', context).click(Drupal.Panels.clickHideAll); 473 $('input#panels-show-all', context).click(Drupal.Panels.clickShowAll); 474 475 Drupal.Panels.bindClickDelete(context); 476 477 $('#panels-live-preview-button:not(.panels-preview-processed)') 478 .addClass('panels-preview-processed') 479 .click(function () { 480 if (!$('#panels-preview').size()) { 481 $('#panels-dnd-main').parents('form').after('<div id="panels-preview"></div>'); 482 } 483 484 $('#panels-preview').html(Drupal.theme('CToolsModalThrobber')); 485 }); 486 487 var setTitleClass = function () { 488 if ($('#edit-display-title-hide-title').val() == 2) { 489 $('#panels-dnd-main').removeClass('panels-set-title-hide'); 490 } 491 else { 492 $('#panels-dnd-main').addClass('panels-set-title-hide'); 493 } 494 } 495 496 // The panes have an option to set the display title, but only if 497 // a select is set to the proper value. This sets a class on the 498 // main edit div so that the option to set the display title 499 // is hidden if that is not selected, and visible if it is. 500 $('#edit-display-title-hide-title:not(.panels-title-processed)') 501 .addClass('panels-title-processed') 502 .change(setTitleClass); 503 504 setTitleClass(); 505 }; 506 507 /** 508 * AJAX responder command to render the preview. 509 */ 510 Drupal.CTools.AJAX.commands.panel_preview = function(command) { 511 $('#panels-preview').html(command.output); 512 } 513 514 })(jQuery);
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Thu Mar 24 11:18:33 2011 | Cross-referenced by PHPXref 0.7 |