[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/lib/yuilib/3.17.2/dd-drag/ -> dd-drag.js (source)

   1  /*
   2  YUI 3.17.2 (build 9c3c78e)
   3  Copyright 2014 Yahoo! Inc. All rights reserved.
   4  Licensed under the BSD License.
   5  http://yuilibrary.com/license/
   6  */
   7  
   8  YUI.add('dd-drag', function (Y, NAME) {
   9  
  10  
  11      /**
  12       * Provides the ability to drag a Node.
  13       * @module dd
  14       * @submodule dd-drag
  15       */
  16      /**
  17       * Provides the ability to drag a Node.
  18       * @class Drag
  19       * @extends Base
  20       * @constructor
  21       * @namespace DD
  22       */
  23  
  24      var DDM = Y.DD.DDM,
  25          NODE = 'node',
  26          DRAGGING = 'dragging',
  27          DRAG_NODE = 'dragNode',
  28          OFFSET_HEIGHT = 'offsetHeight',
  29          OFFSET_WIDTH = 'offsetWidth',
  30          /**
  31          * Handles the mouseup DOM event, does nothing internally just fires.
  32          * @event drag:mouseup
  33          * @bubbles DDM
  34          * @type {CustomEvent}
  35          */
  36          /**
  37          * Handles the mousedown DOM event, checks to see if you have a valid handle then starts the drag timers.
  38          * @event drag:mouseDown
  39          * @preventable _defMouseDownFn
  40          * @param {EventFacade} event An Event Facade object with the following specific property added:
  41          * <dl><dt>ev</dt><dd>The original mousedown event.</dd></dl>
  42          * @bubbles DDM
  43          * @type {CustomEvent}
  44          */
  45          EV_MOUSE_DOWN = 'drag:mouseDown',
  46          /**
  47          * Fires after the mousedown event has been cleared.
  48          * @event drag:afterMouseDown
  49          * @param {EventFacade} event An Event Facade object with the following specific property added:
  50          * <dl><dt>ev</dt><dd>The original mousedown event.</dd></dl>
  51          * @bubbles DDM
  52          * @type {CustomEvent}
  53          */
  54          EV_AFTER_MOUSE_DOWN = 'drag:afterMouseDown',
  55          /**
  56          * Fires after a handle is removed.
  57          * @event drag:removeHandle
  58          * @param {EventFacade} event An Event Facade object with the following specific property added:
  59          * <dl><dt>handle</dt><dd>The handle that was removed.</dd></dl>
  60          * @bubbles DDM
  61          * @type {CustomEvent}
  62          */
  63          EV_REMOVE_HANDLE = 'drag:removeHandle',
  64          /**
  65          * Fires after a handle is added.
  66          * @event drag:addHandle
  67          * @param {EventFacade} event An Event Facade object with the following specific property added:
  68          * <dl><dt>handle</dt><dd>The handle that was added.</dd></dl>
  69          * @bubbles DDM
  70          * @type {CustomEvent}
  71          */
  72          EV_ADD_HANDLE = 'drag:addHandle',
  73          /**
  74          * Fires after an invalid selector is removed.
  75          * @event drag:removeInvalid
  76          * @param {EventFacade} event An Event Facade object with the following specific property added:
  77          * <dl><dt>handle</dt><dd>The handle that was removed.</dd></dl>
  78          * @bubbles DDM
  79          * @type {CustomEvent}
  80          */
  81          EV_REMOVE_INVALID = 'drag:removeInvalid',
  82          /**
  83          * Fires after an invalid selector is added.
  84          * @event drag:addInvalid
  85          * @param {EventFacade} event An Event Facade object with the following specific property added:
  86          * <dl><dt>handle</dt><dd>The handle that was added.</dd></dl>
  87          * @bubbles DDM
  88          * @type {CustomEvent}
  89          */
  90          EV_ADD_INVALID = 'drag:addInvalid',
  91          /**
  92          * Fires at the start of a drag operation.
  93          * @event drag:start
  94          * @param {EventFacade} event An Event Facade object with the following specific property added:
  95          * <dl>
  96          * <dt>pageX</dt><dd>The original node position X.</dd>
  97          * <dt>pageY</dt><dd>The original node position Y.</dd>
  98          * <dt>startTime</dt><dd>The startTime of the event. getTime on the current Date object.</dd>
  99          * </dl>
 100          * @bubbles DDM
 101          * @type {CustomEvent}
 102          */
 103          EV_START = 'drag:start',
 104          /**
 105          * Fires at the end of a drag operation.
 106          * @event drag:end
 107          * @param {EventFacade} event An Event Facade object with the following specific property added:
 108          * <dl>
 109          * <dt>pageX</dt><dd>The current node position X.</dd>
 110          * <dt>pageY</dt><dd>The current node position Y.</dd>
 111          * <dt>startTime</dt><dd>The startTime of the event, from the start event.</dd>
 112          * <dt>endTime</dt><dd>The endTime of the event. getTime on the current Date object.</dd>
 113          * </dl>
 114          * @bubbles DDM
 115          * @type {CustomEvent}
 116          */
 117          EV_END = 'drag:end',
 118          /**
 119          * Fires every mousemove during a drag operation.
 120          * @event drag:drag
 121          * @param {EventFacade} event An Event Facade object with the following specific property added:
 122          * <dl>
 123          * <dt>pageX</dt><dd>The current node position X.</dd>
 124          * <dt>pageY</dt><dd>The current node position Y.</dd>
 125          * <dt>scroll</dt><dd>Should a scroll action occur.</dd>
 126          * <dt>info</dt><dd>Object hash containing calculated XY arrays: start, xy, delta, offset</dd>
 127          * </dl>
 128          * @bubbles DDM
 129          * @type {CustomEvent}
 130          */
 131          EV_DRAG = 'drag:drag',
 132          /**
 133          * Fires when this node is aligned.
 134          * @event drag:align
 135          * @preventable _defAlignFn
 136          * @param {EventFacade} event An Event Facade object with the following specific property added:
 137          * <dl>
 138          * <dt>pageX</dt><dd>The current node position X.</dd>
 139          * <dt>pageY</dt><dd>The current node position Y.</dd>
 140          * </dl>
 141          * @bubbles DDM
 142          * @type {CustomEvent}
 143          */
 144          EV_ALIGN = 'drag:align',
 145          /**
 146          * Fires when this node is over a Drop Target. (Fired from dd-drop)
 147          * @event drag:over
 148          * @param {EventFacade} event An Event Facade object with the following specific property added:
 149          * <dl>
 150          * <dt>drop</dt><dd>The drop object at the time of the event.</dd>
 151          * <dt>drag</dt><dd>The drag object at the time of the event.</dd>
 152          * </dl>
 153          * @bubbles DDM
 154          * @type {CustomEvent}
 155          */
 156          /**
 157          * Fires when this node enters a Drop Target. (Fired from dd-drop)
 158          * @event drag:enter
 159          * @param {EventFacade} event An Event Facade object with the following specific property added:
 160          * <dl>
 161          * <dt>drop</dt><dd>The drop object at the time of the event.</dd>
 162          * <dt>drag</dt><dd>The drag object at the time of the event.</dd>
 163          * </dl>
 164          * @bubbles DDM
 165          * @type {CustomEvent}
 166          */
 167          /**
 168          * Fires when this node exits a Drop Target. (Fired from dd-drop)
 169          * @event drag:exit
 170          * @param {EventFacade} event An Event Facade object with the following specific property added:
 171          * <dl>
 172          * <dt>drop</dt><dd>The drop object at the time of the event.</dd>
 173          * </dl>
 174          * @bubbles DDM
 175          * @type {CustomEvent}
 176          */
 177          /**
 178          * Fires when this node is dropped on a valid Drop Target. (Fired from dd-ddm-drop)
 179          * @event drag:drophit
 180          * @param {EventFacade} event An Event Facade object with the following specific property added:
 181          * <dl>
 182          * <dt>drop</dt><dd>The best guess on what was dropped on.</dd>
 183          * <dt>drag</dt><dd>The drag object at the time of the event.</dd>
 184          * <dt>others</dt><dd>An array of all the other drop targets that was dropped on.</dd>
 185          * </dl>
 186          * @bubbles DDM
 187          * @type {CustomEvent}
 188          */
 189          /**
 190          * Fires when this node is dropped on an invalid Drop Target. (Fired from dd-ddm-drop)
 191          * @event drag:dropmiss
 192          * @param {EventFacade} event An Event Facade object with the following specific property added:
 193          * <dl>
 194          * <dt>pageX</dt><dd>The current node position X.</dd>
 195          * <dt>pageY</dt><dd>The current node position Y.</dd>
 196          * </dl>
 197          * @bubbles DDM
 198          * @type {CustomEvent}
 199          */
 200  
 201      Drag = function(o) {
 202          this._lazyAddAttrs = false;
 203          Drag.superclass.constructor.apply(this, arguments);
 204  
 205          var valid = DDM._regDrag(this);
 206          if (!valid) {
 207              Y.error('Failed to register node, already in use: ' + o.node);
 208          }
 209      };
 210  
 211      Drag.NAME = 'drag';
 212  
 213      /**
 214      * This property defaults to "mousedown", but when drag-gestures is loaded, it is changed to "gesturemovestart"
 215      * @static
 216      * @property START_EVENT
 217      */
 218      Drag.START_EVENT = 'mousedown';
 219  
 220      Drag.ATTRS = {
 221          /**
 222          * Y.Node instance to use as the element to initiate a drag operation
 223          * @attribute node
 224          * @type Node
 225          */
 226          node: {
 227              setter: function(node) {
 228                  if (this._canDrag(node)) {
 229                      return node;
 230                  }
 231                  var n = Y.one(node);
 232                  if (!n) {
 233                      Y.error('DD.Drag: Invalid Node Given: ' + node);
 234                  }
 235                  return n;
 236              }
 237          },
 238          /**
 239          * Y.Node instance to use as the draggable element, defaults to node
 240          * @attribute dragNode
 241          * @type Node
 242          */
 243          dragNode: {
 244              setter: function(node) {
 245                  if (this._canDrag(node)) {
 246                      return node;
 247                  }
 248                  var n = Y.one(node);
 249                  if (!n) {
 250                      Y.error('DD.Drag: Invalid dragNode Given: ' + node);
 251                  }
 252                  return n;
 253              }
 254          },
 255          /**
 256          * Offset the drag element by the difference in cursor position: default true
 257          * @attribute offsetNode
 258          * @type Boolean
 259          */
 260          offsetNode: {
 261              value: true
 262          },
 263          /**
 264          * Center the dragNode to the mouse position on drag:start: default false
 265          * @attribute startCentered
 266          * @type Boolean
 267          */
 268          startCentered: {
 269              value: false
 270          },
 271          /**
 272          * The number of pixels to move to start a drag operation, default is 3.
 273          * @attribute clickPixelThresh
 274          * @type Number
 275          */
 276          clickPixelThresh: {
 277              value: DDM.get('clickPixelThresh')
 278          },
 279          /**
 280          * The number of milliseconds a mousedown has to pass to start a drag operation, default is 1000.
 281          * @attribute clickTimeThresh
 282          * @type Number
 283          */
 284          clickTimeThresh: {
 285              value: DDM.get('clickTimeThresh')
 286          },
 287          /**
 288          * Set to lock this drag element so that it can't be dragged: default false.
 289          * @attribute lock
 290          * @type Boolean
 291          */
 292          lock: {
 293              value: false,
 294              setter: function(lock) {
 295                  if (lock) {
 296                      this.get(NODE).addClass(DDM.CSS_PREFIX + '-locked');
 297                  } else {
 298                      this.get(NODE).removeClass(DDM.CSS_PREFIX + '-locked');
 299                  }
 300                  return lock;
 301              }
 302          },
 303          /**
 304          * A payload holder to store arbitrary data about this drag object, can be used to store any value.
 305          * @attribute data
 306          * @type Mixed
 307          */
 308          data: {
 309              value: false
 310          },
 311          /**
 312          * If this is false, the drag element will not move with the cursor: default true. Can be used to "resize" the element.
 313          * @attribute move
 314          * @type Boolean
 315          */
 316          move: {
 317              value: true
 318          },
 319          /**
 320          * Use the protective shim on all drag operations: default true. Only works with dd-ddm, not dd-ddm-base.
 321          * @attribute useShim
 322          * @type Boolean
 323          */
 324          useShim: {
 325              value: true
 326          },
 327          /**
 328          * Config option is set by Drag to inform you of which handle fired the drag event (in the case that there are several handles): default false.
 329          * @attribute activeHandle
 330          * @type Node
 331          */
 332          activeHandle: {
 333              value: false
 334          },
 335          /**
 336          * By default a drag operation will only begin if the mousedown occurred with the primary mouse button.
 337          * Setting this to false will allow for all mousedown events to trigger a drag.
 338          * @attribute primaryButtonOnly
 339          * @type Boolean
 340          */
 341          primaryButtonOnly: {
 342              value: true
 343          },
 344          /**
 345          * This attribute is not meant to be used by the implementor, it is meant to be used as an Event tracker so you can listen for it to change.
 346          * @attribute dragging
 347          * @type Boolean
 348          */
 349          dragging: {
 350              value: false
 351          },
 352          parent: {
 353              value: false
 354          },
 355          /**
 356          * This attribute only works if the dd-drop module has been loaded. It will make this node a drop target as well as draggable.
 357          * @attribute target
 358          * @type Boolean
 359          */
 360          target: {
 361              value: false,
 362              setter: function(config) {
 363                  this._handleTarget(config);
 364                  return config;
 365              }
 366          },
 367          /**
 368          * This attribute only works if the dd-drop module is active. It will set the dragMode (point, intersect, strict) of this Drag instance.
 369          * @attribute dragMode
 370          * @type String
 371          */
 372          dragMode: {
 373              value: null,
 374              setter: function(mode) {
 375                  return DDM._setDragMode(mode);
 376              }
 377          },
 378          /**
 379          * Array of groups to add this drag into.
 380          * @attribute groups
 381          * @type Array
 382          */
 383          groups: {
 384              value: ['default'],
 385              getter: function() {
 386                  if (!this._groups) {
 387                      this._groups = {};
 388                      return [];
 389                  }
 390  
 391                  return Y.Object.keys(this._groups);
 392              },
 393              setter: function(g) {
 394                  this._groups = Y.Array.hash(g);
 395                  return g;
 396              }
 397          },
 398          /**
 399          * Array of valid handles to add. Adding something here will set all handles, even if previously added with addHandle
 400          * @attribute handles
 401          * @type Array
 402          */
 403          handles: {
 404              value: null,
 405              setter: function(g) {
 406                  if (g) {
 407                      this._handles = {};
 408                      Y.Array.each(g, function(v) {
 409                          var key = v;
 410                          if (v instanceof Y.Node || v instanceof Y.NodeList) {
 411                              key = v._yuid;
 412                          }
 413                          this._handles[key] = v;
 414                      }, this);
 415                  } else {
 416                      this._handles = null;
 417                  }
 418                  return g;
 419              }
 420          },
 421          /**
 422          * Controls the default bubble parent for this Drag instance. Default: Y.DD.DDM. Set to false to disable bubbling. Use bubbleTargets in config
 423          * @deprecated
 424          * @attribute bubbles
 425          * @type Object
 426          */
 427          bubbles: {
 428              setter: function(t) {
 429                  this.addTarget(t);
 430                  return t;
 431              }
 432          },
 433          /**
 434          * Should the mousedown event be halted. Default: true
 435          * @attribute haltDown
 436          * @type Boolean
 437          */
 438          haltDown: {
 439              value: true
 440          }
 441      };
 442  
 443      Y.extend(Drag, Y.Base, {
 444          /**
 445          * Checks the object for the methods needed to drag the object around.
 446          * Normally this would be a node instance, but in the case of Graphics, it
 447          * may be an SVG node or something similar.
 448          * @method _canDrag
 449          * @private
 450          * @param {Object} n The object to check
 451          * @return {Boolean} True or false if the Object contains the methods needed to Drag
 452          */
 453          _canDrag: function(n) {
 454              if (n && n.setXY && n.getXY && n.test && n.contains) {
 455                  return true;
 456              }
 457              return false;
 458          },
 459          /**
 460          * The default bubbleTarget for this object. Default: Y.DD.DDM
 461          * @private
 462          * @property _bubbleTargets
 463          */
 464          _bubbleTargets: Y.DD.DDM,
 465          /**
 466          * Add this Drag instance to a group, this should be used for on-the-fly group additions.
 467          * @method addToGroup
 468          * @param {String} g The group to add this Drag Instance to.
 469          * @chainable
 470          */
 471          addToGroup: function(g) {
 472              this._groups[g] = true;
 473              DDM._activateTargets();
 474              return this;
 475          },
 476          /**
 477          * Remove this Drag instance from a group, this should be used for on-the-fly group removals.
 478          * @method removeFromGroup
 479          * @param {String} g The group to remove this Drag Instance from.
 480          * @chainable
 481          */
 482          removeFromGroup: function(g) {
 483              delete this._groups[g];
 484              DDM._activateTargets();
 485              return this;
 486          },
 487          /**
 488          * This will be a reference to the Drop instance associated with this drag if the target: true config attribute is set..
 489          * @property target
 490          * @type {Object}
 491          */
 492          target: null,
 493          /**
 494          * Attribute handler for the target config attribute.
 495          * @private
 496          * @method _handleTarget
 497          * @param {Boolean/Object} config The Config
 498          */
 499          _handleTarget: function(config) {
 500              if (Y.DD.Drop) {
 501                  if (config === false) {
 502                      if (this.target) {
 503                          DDM._unregTarget(this.target);
 504                          this.target = null;
 505                      }
 506                  } else {
 507                      if (!Y.Lang.isObject(config)) {
 508                          config = {};
 509                      }
 510                      config.bubbleTargets = config.bubbleTargets || this.getTargets();
 511                      config.node = this.get(NODE);
 512                      config.groups = config.groups || this.get('groups');
 513                      this.target = new Y.DD.Drop(config);
 514                  }
 515              }
 516          },
 517          /**
 518          * Storage Array for the groups this drag belongs to.
 519          * @private
 520          * @property _groups
 521          * @type {Array}
 522          */
 523          _groups: null,
 524          /**
 525          * This method creates all the events for this Event Target and publishes them so we get Event Bubbling.
 526          * @private
 527          * @method _createEvents
 528          */
 529          _createEvents: function() {
 530  
 531              this.publish(EV_MOUSE_DOWN, {
 532                  defaultFn: this._defMouseDownFn,
 533                  queuable: false,
 534                  emitFacade: true,
 535                  bubbles: true,
 536                  prefix: 'drag'
 537              });
 538  
 539              this.publish(EV_ALIGN, {
 540                  defaultFn: this._defAlignFn,
 541                  queuable: false,
 542                  emitFacade: true,
 543                  bubbles: true,
 544                  prefix: 'drag'
 545              });
 546  
 547              this.publish(EV_DRAG, {
 548                  defaultFn: this._defDragFn,
 549                  queuable: false,
 550                  emitFacade: true,
 551                  bubbles: true,
 552                  prefix: 'drag'
 553              });
 554  
 555              this.publish(EV_END, {
 556                  defaultFn: this._defEndFn,
 557                  preventedFn: this._prevEndFn,
 558                  queuable: false,
 559                  emitFacade: true,
 560                  bubbles: true,
 561                  prefix: 'drag'
 562              });
 563  
 564              var ev = [
 565                  EV_AFTER_MOUSE_DOWN,
 566                  EV_REMOVE_HANDLE,
 567                  EV_ADD_HANDLE,
 568                  EV_REMOVE_INVALID,
 569                  EV_ADD_INVALID,
 570                  EV_START,
 571                  'drag:drophit',
 572                  'drag:dropmiss',
 573                  'drag:over',
 574                  'drag:enter',
 575                  'drag:exit'
 576              ];
 577  
 578              Y.Array.each(ev, function(v) {
 579                  this.publish(v, {
 580                      type: v,
 581                      emitFacade: true,
 582                      bubbles: true,
 583                      preventable: false,
 584                      queuable: false,
 585                      prefix: 'drag'
 586                  });
 587              }, this);
 588          },
 589          /**
 590          * A private reference to the mousedown DOM event
 591          * @private
 592          * @property _ev_md
 593          * @type {EventFacade}
 594          */
 595          _ev_md: null,
 596          /**
 597          * The getTime of the mousedown event. Not used, just here in case someone wants/needs to use it.
 598          * @private
 599          * @property _startTime
 600          * @type Date
 601          */
 602          _startTime: null,
 603          /**
 604          * The getTime of the mouseup event. Not used, just here in case someone wants/needs to use it.
 605          * @private
 606          * @property _endTime
 607          * @type Date
 608          */
 609          _endTime: null,
 610          /**
 611          * A private hash of the valid drag handles
 612          * @private
 613          * @property _handles
 614          * @type {Object}
 615          */
 616          _handles: null,
 617          /**
 618          * A private hash of the invalid selector strings
 619          * @private
 620          * @property _invalids
 621          * @type {Object}
 622          */
 623          _invalids: null,
 624          /**
 625          * A private hash of the default invalid selector strings: {'textarea': true, 'input': true, 'a': true, 'button': true, 'select': true}
 626          * @private
 627          * @property _invalidsDefault
 628          * @type {Object}
 629          */
 630          _invalidsDefault: {'textarea': true, 'input': true, 'a': true, 'button': true, 'select': true },
 631          /**
 632          * Private flag to see if the drag threshhold was met
 633          * @private
 634          * @property _dragThreshMet
 635          * @type {Boolean}
 636          */
 637          _dragThreshMet: null,
 638          /**
 639          * Flag to determine if the drag operation came from a timeout
 640          * @private
 641          * @property _fromTimeout
 642          * @type {Boolean}
 643          */
 644          _fromTimeout: null,
 645          /**
 646          * Holder for the setTimeout call
 647          * @private
 648          * @property _clickTimeout
 649          * @type {Boolean}
 650          */
 651          _clickTimeout: null,
 652          /**
 653          * The offset of the mouse position to the element's position
 654          * @property deltaXY
 655          * @type {Array}
 656          */
 657          deltaXY: null,
 658          /**
 659          * The initial mouse position
 660          * @property startXY
 661          * @type {Array}
 662          */
 663          startXY: null,
 664          /**
 665          * The initial element position
 666          * @property nodeXY
 667          * @type {Array}
 668          */
 669          nodeXY: null,
 670          /**
 671          * The position of the element as it's moving (for offset calculations)
 672          * @property lastXY
 673          * @type {Array}
 674          */
 675          lastXY: null,
 676          /**
 677          * The xy that the node will be set to. Changing this will alter the position as it's dragged.
 678          * @property actXY
 679          * @type {Array}
 680          */
 681          actXY: null,
 682          /**
 683          * The real xy position of the node.
 684          * @property realXY
 685          * @type {Array}
 686          */
 687          realXY: null,
 688          /**
 689          * The XY coords of the mousemove
 690          * @property mouseXY
 691          * @type {Array}
 692          */
 693          mouseXY: null,
 694          /**
 695          * A region object associated with this drag, used for checking regions while dragging.
 696          * @property region
 697          * @type Object
 698          */
 699          region: null,
 700          /**
 701          * Handler for the mouseup DOM event
 702          * @private
 703          * @method _handleMouseUp
 704          * @param {EventFacade} ev The Event
 705          */
 706          _handleMouseUp: function() {
 707              this.fire('drag:mouseup');
 708              this._fixIEMouseUp();
 709              if (DDM.activeDrag) {
 710                  DDM._end();
 711              }
 712          },
 713          /**
 714          * The function we use as the ondragstart handler when we start a drag
 715          * in Internet Explorer. This keeps IE from blowing up on images as drag handles.
 716          * @private
 717          * @method _fixDragStart
 718          * @param {Event} e The Event
 719          */
 720          _fixDragStart: function(e) {
 721              if (this.validClick(e)) {
 722                  e.preventDefault();
 723              }
 724          },
 725          /**
 726          * The function we use as the onselectstart handler when we start a drag in Internet Explorer
 727          * @private
 728          * @method _ieSelectFix
 729          */
 730          _ieSelectFix: function() {
 731              return false;
 732          },
 733          /**
 734          * We will hold a copy of the current "onselectstart" method on this property, and reset it after we are done using it.
 735          * @private
 736          * @property _ieSelectBack
 737          */
 738          _ieSelectBack: null,
 739          /**
 740          * This method copies the onselectstart listner on the document to the _ieSelectFix property
 741          * @private
 742          * @method _fixIEMouseDown
 743          */
 744          _fixIEMouseDown: function() {
 745              if (Y.UA.ie) {
 746                  this._ieSelectBack = Y.config.doc.body.onselectstart;
 747                  Y.config.doc.body.onselectstart = this._ieSelectFix;
 748              }
 749          },
 750          /**
 751          * This method copies the _ieSelectFix property back to the onselectstart listner on the document.
 752          * @private
 753          * @method _fixIEMouseUp
 754          */
 755          _fixIEMouseUp: function() {
 756              if (Y.UA.ie) {
 757                  Y.config.doc.body.onselectstart = this._ieSelectBack;
 758              }
 759          },
 760          /**
 761          * Handler for the mousedown DOM event
 762          * @private
 763          * @method _handleMouseDownEvent
 764          * @param {EventFacade} ev  The Event
 765          */
 766          _handleMouseDownEvent: function(ev) {
 767              if (this.validClick(ev)) {
 768                  ev.preventDefault();
 769              }
 770              this.fire(EV_MOUSE_DOWN, { ev: ev });
 771          },
 772          /**
 773          * Handler for the mousedown DOM event
 774          * @private
 775          * @method _defMouseDownFn
 776          * @param {EventFacade} e  The Event
 777          */
 778          _defMouseDownFn: function(e) {
 779              var ev = e.ev;
 780  
 781              this._dragThreshMet = false;
 782              this._ev_md = ev;
 783  
 784              if (this.get('primaryButtonOnly') && ev.button > 1) {
 785                  return false;
 786              }
 787              if (this.validClick(ev)) {
 788                  this._fixIEMouseDown(ev);
 789                  if (Drag.START_EVENT.indexOf('gesture') !== 0) {
 790                      //Only do these if it's not a gesture
 791                      if (this.get('haltDown')) {
 792                          ev.halt();
 793                      } else {
 794                          ev.preventDefault();
 795                      }
 796                  }
 797  
 798                  this._setStartPosition([ev.pageX, ev.pageY]);
 799  
 800                  DDM.activeDrag = this;
 801  
 802                  this._clickTimeout = Y.later(this.get('clickTimeThresh'), this, this._timeoutCheck);
 803              }
 804              this.fire(EV_AFTER_MOUSE_DOWN, { ev: ev });
 805          },
 806          /**
 807          * Method first checks to see if we have handles, if so it validates the click
 808          * against the handle. Then if it finds a valid handle, it checks it against
 809          * the invalid handles list. Returns true if a good handle was used, false otherwise.
 810          * @method validClick
 811          * @param {EventFacade} ev  The Event
 812          * @return {Boolean}
 813          */
 814          validClick: function(ev) {
 815              var r = false, n = false,
 816              tar = ev.target,
 817              hTest = null,
 818              els = null,
 819              nlist = null,
 820              set = false;
 821              if (this._handles) {
 822                  Y.Object.each(this._handles, function(i, n) {
 823                      if (i instanceof Y.Node || i instanceof Y.NodeList) {
 824                          if (!r) {
 825                              nlist = i;
 826                              if (nlist instanceof Y.Node) {
 827                                  nlist = new Y.NodeList(i._node);
 828                              }
 829                              nlist.each(function(nl) {
 830                                  if (nl.contains(tar)) {
 831                                      r = true;
 832                                  }
 833                              });
 834                          }
 835                      } else if (Y.Lang.isString(n)) {
 836                          //Am I this or am I inside this
 837                          if (tar.test(n + ', ' + n + ' *') && !hTest) {
 838                              hTest = n;
 839                              r = true;
 840                          }
 841                      }
 842                  });
 843              } else {
 844                  n = this.get(NODE);
 845                  if (n.contains(tar) || n.compareTo(tar)) {
 846                      r = true;
 847                  }
 848              }
 849              if (r) {
 850                  if (this._invalids) {
 851                      Y.Object.each(this._invalids, function(i, n) {
 852                          if (Y.Lang.isString(n)) {
 853                              //Am I this or am I inside this
 854                              if (tar.test(n + ', ' + n + ' *')) {
 855                                  r = false;
 856                              }
 857                          }
 858                      });
 859                  }
 860              }
 861              if (r) {
 862                  if (hTest) {
 863                      els = ev.currentTarget.all(hTest);
 864                      set = false;
 865                      els.each(function(n) {
 866                          if ((n.contains(tar) || n.compareTo(tar)) && !set) {
 867                              set = true;
 868                              this.set('activeHandle', n);
 869                          }
 870                      }, this);
 871                  } else {
 872                      this.set('activeHandle', this.get(NODE));
 873                  }
 874              }
 875              return r;
 876          },
 877          /**
 878          * Sets the current position of the Element and calculates the offset
 879          * @private
 880          * @method _setStartPosition
 881          * @param {Array} xy The XY coords to set the position to.
 882          */
 883          _setStartPosition: function(xy) {
 884              this.startXY = xy;
 885  
 886              this.nodeXY = this.lastXY = this.realXY = this.get(NODE).getXY();
 887  
 888              if (this.get('offsetNode')) {
 889                  this.deltaXY = [(this.startXY[0] - this.nodeXY[0]), (this.startXY[1] - this.nodeXY[1])];
 890              } else {
 891                  this.deltaXY = [0, 0];
 892              }
 893          },
 894          /**
 895          * The method passed to setTimeout to determine if the clickTimeThreshold was met.
 896          * @private
 897          * @method _timeoutCheck
 898          */
 899          _timeoutCheck: function() {
 900              if (!this.get('lock') && !this._dragThreshMet && this._ev_md) {
 901                  this._fromTimeout = this._dragThreshMet = true;
 902                  this.start();
 903                  this._alignNode([this._ev_md.pageX, this._ev_md.pageY], true);
 904              }
 905          },
 906          /**
 907          * Remove a Selector added by addHandle
 908          * @method removeHandle
 909          * @param {String} str The selector for the handle to be removed.
 910          * @chainable
 911          */
 912          removeHandle: function(str) {
 913              var key = str;
 914              if (str instanceof Y.Node || str instanceof Y.NodeList) {
 915                  key = str._yuid;
 916              }
 917              if (this._handles[key]) {
 918                  delete this._handles[key];
 919                  this.fire(EV_REMOVE_HANDLE, { handle: str });
 920              }
 921              return this;
 922          },
 923          /**
 924          * Add a handle to a drag element. Drag only initiates when a mousedown happens on this element.
 925          * @method addHandle
 926          * @param {String} str The selector to test for a valid handle. Must be a child of the element.
 927          * @chainable
 928          */
 929          addHandle: function(str) {
 930              if (!this._handles) {
 931                  this._handles = {};
 932              }
 933              var key = str;
 934              if (str instanceof Y.Node || str instanceof Y.NodeList) {
 935                  key = str._yuid;
 936              }
 937              this._handles[key] = str;
 938              this.fire(EV_ADD_HANDLE, { handle: str });
 939              return this;
 940          },
 941          /**
 942          * Remove an invalid handle added by addInvalid
 943          * @method removeInvalid
 944          * @param {String} str The invalid handle to remove from the internal list.
 945          * @chainable
 946          */
 947          removeInvalid: function(str) {
 948              if (this._invalids[str]) {
 949                  this._invalids[str] = null;
 950                  delete this._invalids[str];
 951                  this.fire(EV_REMOVE_INVALID, { handle: str });
 952              }
 953              return this;
 954          },
 955          /**
 956          * Add a selector string to test the handle against. If the test passes the drag operation will not continue.
 957          * @method addInvalid
 958          * @param {String} str The selector to test against to determine if this is an invalid drag handle.
 959          * @chainable
 960          */
 961          addInvalid: function(str) {
 962              if (Y.Lang.isString(str)) {
 963                  this._invalids[str] = true;
 964                  this.fire(EV_ADD_INVALID, { handle: str });
 965              }
 966              return this;
 967          },
 968          /**
 969          * Internal init handler
 970          * @private
 971          * @method initializer
 972          */
 973          initializer: function() {
 974  
 975              this.get(NODE).dd = this;
 976  
 977              if (!this.get(NODE).get('id')) {
 978                  var id = Y.stamp(this.get(NODE));
 979                  this.get(NODE).set('id', id);
 980              }
 981  
 982              this.actXY = [];
 983  
 984              this._invalids = Y.clone(this._invalidsDefault, true);
 985  
 986              this._createEvents();
 987  
 988              if (!this.get(DRAG_NODE)) {
 989                  this.set(DRAG_NODE, this.get(NODE));
 990              }
 991  
 992              //Fix for #2528096
 993              //Don't prep the DD instance until all plugins are loaded.
 994              this.on('initializedChange', Y.bind(this._prep, this));
 995  
 996              //Shouldn't have to do this..
 997              this.set('groups', this.get('groups'));
 998          },
 999          /**
1000          * Attach event listners and add classname
1001          * @private
1002          * @method _prep
1003          */
1004          _prep: function() {
1005              this._dragThreshMet = false;
1006              var node = this.get(NODE);
1007              node.addClass(DDM.CSS_PREFIX + '-draggable');
1008              node.on(Drag.START_EVENT, Y.bind(this._handleMouseDownEvent, this));
1009              node.on('mouseup', Y.bind(this._handleMouseUp, this));
1010              node.on('dragstart', Y.bind(this._fixDragStart, this));
1011          },
1012          /**
1013          * Detach event listeners and remove classname
1014          * @private
1015          * @method _unprep
1016          */
1017          _unprep: function() {
1018              var node = this.get(NODE);
1019              node.removeClass(DDM.CSS_PREFIX + '-draggable');
1020              node.detachAll('mouseup');
1021              node.detachAll('dragstart');
1022              node.detachAll(Drag.START_EVENT);
1023              this.mouseXY = [];
1024              this.deltaXY = [0,0];
1025              this.startXY = [];
1026              this.nodeXY = [];
1027              this.lastXY = [];
1028              this.actXY = [];
1029              this.realXY = [];
1030          },
1031          /**
1032          * Starts the drag operation
1033          * @method start
1034          * @chainable
1035          */
1036          start: function() {
1037              if (!this.get('lock') && !this.get(DRAGGING)) {
1038                  var node = this.get(NODE), ow, oh, xy;
1039                  this._startTime = (new Date()).getTime();
1040  
1041                  DDM._start();
1042                  node.addClass(DDM.CSS_PREFIX + '-dragging');
1043                  this.fire(EV_START, {
1044                      pageX: this.nodeXY[0],
1045                      pageY: this.nodeXY[1],
1046                      startTime: this._startTime
1047                  });
1048                  node = this.get(DRAG_NODE);
1049                  xy = this.nodeXY;
1050  
1051                  ow = node.get(OFFSET_WIDTH);
1052                  oh = node.get(OFFSET_HEIGHT);
1053  
1054                  if (this.get('startCentered')) {
1055                      this._setStartPosition([xy[0] + (ow / 2), xy[1] + (oh / 2)]);
1056                  }
1057  
1058  
1059                  this.region = {
1060                      '0': xy[0],
1061                      '1': xy[1],
1062                      area: 0,
1063                      top: xy[1],
1064                      right: xy[0] + ow,
1065                      bottom: xy[1] + oh,
1066                      left: xy[0]
1067                  };
1068                  this.set(DRAGGING, true);
1069              }
1070              return this;
1071          },
1072          /**
1073          * Ends the drag operation
1074          * @method end
1075          * @chainable
1076          */
1077          end: function() {
1078              this._endTime = (new Date()).getTime();
1079              if (this._clickTimeout) {
1080                  this._clickTimeout.cancel();
1081              }
1082              this._dragThreshMet = this._fromTimeout = false;
1083  
1084              if (!this.get('lock') && this.get(DRAGGING)) {
1085                  this.fire(EV_END, {
1086                      pageX: this.lastXY[0],
1087                      pageY: this.lastXY[1],
1088                      startTime: this._startTime,
1089                      endTime: this._endTime
1090                  });
1091              }
1092              this.get(NODE).removeClass(DDM.CSS_PREFIX + '-dragging');
1093              this.set(DRAGGING, false);
1094              this.deltaXY = [0, 0];
1095  
1096              return this;
1097          },
1098          /**
1099          * Handler for fixing the selection in IE
1100          * @private
1101          * @method _defEndFn
1102          */
1103          _defEndFn: function() {
1104              this._fixIEMouseUp();
1105              this._ev_md = null;
1106          },
1107          /**
1108          * Handler for preventing the drag:end event. It will reset the node back to it's start position
1109          * @private
1110          * @method _prevEndFn
1111          */
1112          _prevEndFn: function() {
1113              this._fixIEMouseUp();
1114              //Bug #1852577
1115              this.get(DRAG_NODE).setXY(this.nodeXY);
1116              this._ev_md = null;
1117              this.region = null;
1118          },
1119          /**
1120          * Calculates the offsets and set's the XY that the element will move to.
1121          * @private
1122          * @method _align
1123          * @param {Array} xy The xy coords to align with.
1124          */
1125          _align: function(xy) {
1126              this.fire(EV_ALIGN, {pageX: xy[0], pageY: xy[1] });
1127          },
1128          /**
1129          * Calculates the offsets and set's the XY that the element will move to.
1130          * @private
1131          * @method _defAlignFn
1132          * @param {EventFacade} e The drag:align event.
1133          */
1134          _defAlignFn: function(e) {
1135              this.actXY = [e.pageX - this.deltaXY[0], e.pageY - this.deltaXY[1]];
1136          },
1137          /**
1138          * This method performs the alignment before the element move.
1139          * @private
1140          * @method _alignNode
1141          * @param {Array} eXY The XY to move the element to, usually comes from the mousemove DOM event.
1142          */
1143          _alignNode: function(eXY, scroll) {
1144              this._align(eXY);
1145              if (!scroll) {
1146                  this._moveNode();
1147              }
1148          },
1149          /**
1150          * This method performs the actual element move.
1151          * @private
1152          * @method _moveNode
1153          */
1154          _moveNode: function(scroll) {
1155              //if (!this.get(DRAGGING)) {
1156              //    return;
1157              //}
1158              var diffXY = [], diffXY2 = [], startXY = this.nodeXY, xy = this.actXY;
1159  
1160              diffXY[0] = (xy[0] - this.lastXY[0]);
1161              diffXY[1] = (xy[1] - this.lastXY[1]);
1162  
1163              diffXY2[0] = (xy[0] - this.nodeXY[0]);
1164              diffXY2[1] = (xy[1] - this.nodeXY[1]);
1165  
1166  
1167              this.region = {
1168                  '0': xy[0],
1169                  '1': xy[1],
1170                  area: 0,
1171                  top: xy[1],
1172                  right: xy[0] + this.get(DRAG_NODE).get(OFFSET_WIDTH),
1173                  bottom: xy[1] + this.get(DRAG_NODE).get(OFFSET_HEIGHT),
1174                  left: xy[0]
1175              };
1176  
1177              this.fire(EV_DRAG, {
1178                  pageX: xy[0],
1179                  pageY: xy[1],
1180                  scroll: scroll,
1181                  info: {
1182                      start: startXY,
1183                      xy: xy,
1184                      delta: diffXY,
1185                      offset: diffXY2
1186                  }
1187              });
1188  
1189              this.lastXY = xy;
1190          },
1191          /**
1192          * Default function for drag:drag. Fired from _moveNode.
1193          * @private
1194          * @method _defDragFn
1195          * @param {EventFacade} ev The drag:drag event
1196          */
1197          _defDragFn: function(e) {
1198              if (this.get('move')) {
1199                  if (e.scroll && e.scroll.node) {
1200                      var domNode = e.scroll.node.getDOMNode();
1201                      //If it's the window
1202                      if (domNode === Y.config.win) {
1203                          domNode.scrollTo(e.scroll.left, e.scroll.top);
1204                      } else {
1205                          e.scroll.node.set('scrollTop', e.scroll.top);
1206                          e.scroll.node.set('scrollLeft', e.scroll.left);
1207                      }
1208                  }
1209                  this.get(DRAG_NODE).setXY([e.pageX, e.pageY]);
1210                  this.realXY = [e.pageX, e.pageY];
1211              }
1212          },
1213          /**
1214          * Fired from DragDropMgr (DDM) on mousemove.
1215          * @private
1216          * @method _move
1217          * @param {EventFacade} ev The mousemove DOM event
1218          */
1219          _move: function(ev) {
1220              if (this.get('lock')) {
1221                  return false;
1222              }
1223  
1224              this.mouseXY = [ev.pageX, ev.pageY];
1225              if (!this._dragThreshMet) {
1226                  var diffX = Math.abs(this.startXY[0] - ev.pageX),
1227                  diffY = Math.abs(this.startXY[1] - ev.pageY);
1228                  if (diffX > this.get('clickPixelThresh') || diffY > this.get('clickPixelThresh')) {
1229                      this._dragThreshMet = true;
1230                      this.start();
1231                      //This only happens on gestures to stop the page from scrolling
1232                      if (ev && ev.preventDefault) {
1233                          ev.preventDefault();
1234                      }
1235                      this._alignNode([ev.pageX, ev.pageY]);
1236                  }
1237              } else {
1238                  if (this._clickTimeout) {
1239                      this._clickTimeout.cancel();
1240                  }
1241                  this._alignNode([ev.pageX, ev.pageY]);
1242              }
1243          },
1244          /**
1245          * Method will forcefully stop a drag operation. For example calling this from inside an ESC keypress handler will stop this drag.
1246          * @method stopDrag
1247          * @chainable
1248          */
1249          stopDrag: function() {
1250              if (this.get(DRAGGING)) {
1251                  DDM._end();
1252              }
1253              return this;
1254          },
1255          /**
1256          * Lifecycle destructor, unreg the drag from the DDM and remove listeners
1257          * @private
1258          * @method destructor
1259          */
1260          destructor: function() {
1261              this._unprep();
1262              if (this.target) {
1263                  this.target.destroy();
1264              }
1265              DDM._unregDrag(this);
1266          }
1267      });
1268      Y.namespace('DD');
1269      Y.DD.Drag = Drag;
1270  
1271  
1272  
1273  
1274  }, '3.17.2', {"requires": ["dd-ddm-base"]});


Generated: Thu Aug 11 10:00:09 2016 Cross-referenced by PHPXref 0.7.1