source: sipes/modules_contrib/panels/js/display_editor.js @ 4f375e3

stableversion-3.0
Last change on this file since 4f375e3 was 4f375e3, checked in by José Gregorio Puentes <jpuentes@…>, 8 años ago

se agrego el modulo panels

  • Propiedad mode establecida a 100644
File size: 17.0 KB
Línea 
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">&nbsp;</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();
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();
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);
Nota: Vea TracBrowser para ayuda de uso del navegador del repositorio.