[ Index ]

PHP Cross Reference of Drupal 6 (gatewave)

title

Body

[close]

/sites/all/modules/panels/js/ -> display_editor.js (source)

   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">&nbsp;</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);


Generated: Thu Mar 24 11:18:33 2011 Cross-referenced by PHPXref 0.7