topical media & game development

talk show tell print

lib-jquery-style-custom-development-bundle-ui-ui.droppable.js / js



  /*
   * jQuery UI Droppable 1.7.1
   *
   * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
   * Dual licensed under the MIT (MIT-LICENSE.txt)
   * and GPL (GPL-LICENSE.txt) licenses.
   *
   * http://docs.jquery.com/UI/Droppables
   *
   * Depends:
   *        ui.core.js
   *        ui.draggable.js
   */
  (function() {
  
  .widget("ui.droppable", {
  
          _init: function() {
  
                  var o = this.options, accept = o.accept;
                  this.isover = 0; this.isout = 1;
  
                  this.options.accept = this.options.accept && .isFunction(this.options.accept) ? this.options.accept : function(d) {
                          return d.is(accept);
                  };
  
                  //Store the droppable's proportions
                  this.proportions = { width: this.element[0].offsetWidth, height: this.element[0].offsetHeight };
  
                  // Add the reference and positions to the manager
                  .ui.ddmanager.droppables[this.options.scope] = .ui.ddmanager.droppables[this.options.scope] || [];
                  .ui.ddmanager.droppables[this.options.scope].push(this);
  
                  (this.options.addClasses && this.element.addClass("ui-droppable"));
  
          },
  
          destroy: function() {
                  var drop = .ui.ddmanager.droppables[this.options.scope];
                  for ( var i = 0; i < drop.length; i++ )
                          if ( drop[i] == this )
                                  drop.splice(i, 1);
  
                  this.element
                          .removeClass("ui-droppable ui-droppable-disabled")
                          .removeData("droppable")
                          .unbind(".droppable");
          },
  
          _setData: function(key, value) {
  
                  if(key == 'accept') {
                          this.options.accept = value && .isFunction(value) ? value : function(d) {
                                  return d.is(value);
                          };
                  } else {
                          .widget.prototype._setData.apply(this, arguments);
                  }
  
          },
  
          _activate: function(event) {
                  var draggable = .ui.ddmanager.current;
                  if(this.options.activeClass) this.element.addClass(this.options.activeClass);
                  (draggable && this._trigger('activate', event, this.ui(draggable)));
          },
  
          _deactivate: function(event) {
                  var draggable = .ui.ddmanager.current;
                  if(this.options.activeClass) this.element.removeClass(this.options.activeClass);
                  (draggable && this._trigger('deactivate', event, this.ui(draggable)));
          },
  
          _over: function(event) {
  
                  var draggable = .ui.ddmanager.current;
                  if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element
  
                  if (this.options.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
                          if(this.options.hoverClass) this.element.addClass(this.options.hoverClass);
                          this._trigger('over', event, this.ui(draggable));
                  }
  
          },
  
          _out: function(event) {
  
                  var draggable = .ui.ddmanager.current;
                  if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element
  
                  if (this.options.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
                          if(this.options.hoverClass) this.element.removeClass(this.options.hoverClass);
                          this._trigger('out', event, this.ui(draggable));
                  }
  
          },
  
          _drop: function(event,custom) {
  
                  var draggable = custom || .ui.ddmanager.current;
                  if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return false; // Bail if draggable and droppable are same element
  
                  var childrenIntersection = false;
                  this.element.find(":data(droppable)").not(".ui-draggable-dragging").each(function() {
                          var inst = .data(this, 'droppable');
                          if(inst.options.greedy && .ui.intersect(draggable, .extend(inst, { offset: inst.element.offset() }), inst.options.tolerance)) {
                                  childrenIntersection = true; return false;
                          }
                  });
                  if(childrenIntersection) return false;
  
                  if(this.options.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
                          if(this.options.activeClass) this.element.removeClass(this.options.activeClass);
                          if(this.options.hoverClass) this.element.removeClass(this.options.hoverClass);
                          this._trigger('drop', event, this.ui(draggable));
                          return this.element;
                  }
  
                  return false;
  
          },
  
          ui: function(c) {
                  return {
                          draggable: (c.currentItem || c.element),
                          helper: c.helper,
                          position: c.position,
                          absolutePosition: c.positionAbs, //deprecated
                          offset: c.positionAbs
                  };
          }
  
  });
  
  .extend(.ui.droppable, {
          version: "1.7.1",
          eventPrefix: 'drop',
          defaults: {
                  accept: '*',
                  activeClass: false,
                  addClasses: true,
                  greedy: false,
                  hoverClass: false,
                  scope: 'default',
                  tolerance: 'intersect'
          }
  });
  
  .ui.intersect = function(draggable, droppable, toleranceMode) {
  
          if (!droppable.offset) return false;
  
          var x1 = (draggable.positionAbs || draggable.position.absolute).left, x2 = x1 + draggable.helperProportions.width,
                  y1 = (draggable.positionAbs || draggable.position.absolute).top, y2 = y1 + draggable.helperProportions.height;
          var l = droppable.offset.left, r = l + droppable.proportions.width,
                  t = droppable.offset.top, b = t + droppable.proportions.height;
  
          switch (toleranceMode) {
                  case 'fit':
                          return (l < x1 && x2 < r
                                  && t < y1 && y2 < b);
                          break;
                  case 'intersect':
                          return (l < x1 + (draggable.helperProportions.width / 2) // Right Half
                                  && x2 - (draggable.helperProportions.width / 2) < r // Left Half
                                  && t < y1 + (draggable.helperProportions.height / 2) // Bottom Half
                                  && y2 - (draggable.helperProportions.height / 2) < b ); // Top Half
                          break;
                  case 'pointer':
                          var draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left),
                                  draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top),
                                  isOver = .ui.isOver(draggableTop, draggableLeft, t, l, droppable.proportions.height, droppable.proportions.width);
                          return isOver;
                          break;
                  case 'touch':
                          return (
                                          (y1 >= t && y1 <= b) ||        // Top edge touching
                                          (y2 >= t && y2 <= b) ||        // Bottom edge touching
                                          (y1 < t && y2 > b)                // Surrounded vertically
                                  ) && (
                                          (x1 >= l && x1 <= r) ||        // Left edge touching
                                          (x2 >= l && x2 <= r) ||        // Right edge touching
                                          (x1 < l && x2 > r)                // Surrounded horizontally
                                  );
                          break;
                  default:
                          return false;
                          break;
                  }
  
  };
  
  /*
          This manager tracks offsets of draggables and droppables
  */
  .ui.ddmanager = {
          current: null,
          droppables: { 'default': [] },
          prepareOffsets: function(t, event) {
  
                  var m = .ui.ddmanager.droppables[t.options.scope];
                  var type = event ? event.type : null; // workaround for #2317
                  var list = (t.currentItem || t.element).find(":data(droppable)").andSelf();
  
                  droppablesLoop: for (var i = 0; i < m.length; i++) {
  
                          if(m[i].options.disabled || (t && !m[i].options.accept.call(m[i].element[0],(t.currentItem || t.element)))) continue;        //No disabled and non-accepted
                          for (var j=0; j < list.length; j++) { if(list[j] == m[i].element[0]) { m[i].proportions.height = 0; continue droppablesLoop; } }; //Filter out elements in the current dragged item
                          m[i].visible = m[i].element.css("display") != "none"; if(!m[i].visible) continue;                                                                         //If the element is not visible, continue
  
                          m[i].offset = m[i].element.offset();
                          m[i].proportions = { width: m[i].element[0].offsetWidth, height: m[i].element[0].offsetHeight };
  
                          if(type == "mousedown") m[i]._activate.call(m[i], event); //Activate the droppable if used directly from draggables
  
                  }
  
          },
          drop: function(draggable, event) {
  
                  var dropped = false;
                  .each(.ui.ddmanager.droppables[draggable.options.scope], function() {
  
                          if(!this.options) return;
                          if (!this.options.disabled && this.visible && .ui.intersect(draggable, this, this.options.tolerance))
                                  dropped = this._drop.call(this, event);
  
                          if (!this.options.disabled && this.visible && this.options.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
                                  this.isout = 1; this.isover = 0;
                                  this._deactivate.call(this, event);
                          }
  
                  });
                  return dropped;
  
          },
          drag: function(draggable, event) {
  
                  //If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse.
                  if(draggable.options.refreshPositions) .ui.ddmanager.prepareOffsets(draggable, event);
  
                  //Run through all droppables and check their positions based on specific tolerance options
  
                  .each(.ui.ddmanager.droppables[draggable.options.scope], function() {
  
                          if(this.options.disabled || this.greedyChild || !this.visible) return;
                          var intersects = .ui.intersect(draggable, this, this.options.tolerance);
  
                          var c = !intersects && this.isover == 1 ? 'isout' : (intersects && this.isover == 0 ? 'isover' : null);
                          if(!c) return;
  
                          var parentInstance;
                          if (this.options.greedy) {
                                  var parent = this.element.parents(':data(droppable):eq(0)');
                                  if (parent.length) {
                                          parentInstance = .data(parent[0], 'droppable');
                                          parentInstance.greedyChild = (c == 'isover' ? 1 : 0);
                                  }
                          }
  
                          // we just moved into a greedy child
                          if (parentInstance && c == 'isover') {
                                  parentInstance['isover'] = 0;
                                  parentInstance['isout'] = 1;
                                  parentInstance._out.call(parentInstance, event);
                          }
  
                          this[c] = 1; this[c == 'isout' ? 'isover' : 'isout'] = 0;
                          this[c == "isover" ? "_over" : "_out"].call(this, event);
  
                          // we just moved out of a greedy child
                          if (parentInstance && c == 'isout') {
                                  parentInstance['isout'] = 0;
                                  parentInstance['isover'] = 1;
                                  parentInstance._over.call(parentInstance, event);
                          }
                  });
  
          }
  };
  
  })(jQuery);
  


(C) Æliens 20/2/2008

You may not copy or print any of this material without explicit permission of the author or the publisher. In case of other copyright issues, contact the author.