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