[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/lib/yuilib/3.17.2/widget-position-align/ -> widget-position-align-debug.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('widget-position-align', function (Y, NAME) {
   9  
  10  /**
  11  Provides extended/advanced XY positioning support for Widgets, through an
  12  extension.
  13  
  14  It builds on top of the `widget-position` module, to provide alignment and
  15  centering support. Future releases aim to add constrained and fixed positioning
  16  support.
  17  
  18  @module widget-position-align
  19  **/
  20  var Lang = Y.Lang,
  21  
  22      ALIGN        = 'align',
  23      ALIGN_ON     = 'alignOn',
  24  
  25      VISIBLE      = 'visible',
  26      BOUNDING_BOX = 'boundingBox',
  27  
  28      OFFSET_WIDTH    = 'offsetWidth',
  29      OFFSET_HEIGHT   = 'offsetHeight',
  30      REGION          = 'region',
  31      VIEWPORT_REGION = 'viewportRegion';
  32  
  33  /**
  34  Widget extension, which can be used to add extended XY positioning support to
  35  the base Widget class, through the `Base.create` method.
  36  
  37  **Note:** This extension requires that the `WidgetPosition` extension be added
  38  to the Widget (before `WidgetPositionAlign`, if part of the same extension list
  39  passed to `Base.build`).
  40  
  41  @class WidgetPositionAlign
  42  @param {Object} config User configuration object.
  43  @constructor
  44  **/
  45  function PositionAlign (config) {}
  46  
  47  PositionAlign.ATTRS = {
  48  
  49      /**
  50      The alignment configuration for this widget.
  51  
  52      The `align` attribute is used to align a reference point on the widget, with
  53      the reference point on another `Node`, or the viewport. The object which
  54      `align` expects has the following properties:
  55  
  56        * __`node`__: The `Node` to which the widget is to be aligned. If set to
  57          `null`, or not provided, the widget is aligned to the viewport.
  58  
  59        * __`points`__: A two element Array, defining the two points on the widget
  60          and `Node`/viewport which are to be aligned. The first element is the
  61          point on the widget, and the second element is the point on the
  62          `Node`/viewport. Supported alignment points are defined as static
  63          properties on `WidgetPositionAlign`.
  64  
  65      @example Aligns the top-right corner of the widget with the top-left corner
  66      of the viewport:
  67  
  68          myWidget.set('align', {
  69              points: [Y.WidgetPositionAlign.TR, Y.WidgetPositionAlign.TL]
  70          });
  71  
  72      @attribute align
  73      @type Object
  74      @default null
  75      **/
  76      align: {
  77          value: null
  78      },
  79  
  80      /**
  81      A convenience Attribute, which can be used as a shortcut for the `align`
  82      Attribute.
  83  
  84      If set to `true`, the widget is centered in the viewport. If set to a `Node`
  85      reference or valid selector String, the widget will be centered within the
  86      `Node`. If set to `false`, no center positioning is applied.
  87  
  88      @attribute centered
  89      @type Boolean|Node
  90      @default false
  91      **/
  92      centered: {
  93          setter : '_setAlignCenter',
  94          lazyAdd:false,
  95          value  :false
  96      },
  97  
  98      /**
  99      An Array of Objects corresponding to the `Node`s and events that will cause
 100      the alignment of this widget to be synced to the DOM.
 101  
 102      The `alignOn` Attribute is expected to be an Array of Objects with the
 103      following properties:
 104  
 105        * __`eventName`__: The String event name to listen for.
 106  
 107        * __`node`__: The optional `Node` that will fire the event, it can be a
 108          `Node` reference or a selector String. This will default to the widget's
 109          `boundingBox`.
 110  
 111      @example Sync this widget's alignment on window resize:
 112  
 113          myWidget.set('alignOn', [
 114              {
 115                  node     : Y.one('win'),
 116                  eventName: 'resize'
 117              }
 118          ]);
 119  
 120      @attribute alignOn
 121      @type Array
 122      @default []
 123      **/
 124      alignOn: {
 125          value    : [],
 126          validator: Y.Lang.isArray
 127      }
 128  };
 129  
 130  /**
 131  Constant used to specify the top-left corner for alignment
 132  
 133  @property TL
 134  @type String
 135  @value 'tl'
 136  @static
 137  **/
 138  PositionAlign.TL = 'tl';
 139  
 140  /**
 141  Constant used to specify the top-right corner for alignment
 142  
 143  @property TR
 144  @type String
 145  @value 'tr'
 146  @static
 147  **/
 148  PositionAlign.TR = 'tr';
 149  
 150  /**
 151  Constant used to specify the bottom-left corner for alignment
 152  
 153  @property BL
 154  @type String
 155  @value 'bl'
 156  @static
 157  **/
 158  PositionAlign.BL = 'bl';
 159  
 160  /**
 161  Constant used to specify the bottom-right corner for alignment
 162  
 163  @property BR
 164  @type String
 165  @value 'br'
 166  @static
 167  **/
 168  PositionAlign.BR = 'br';
 169  
 170  /**
 171  Constant used to specify the top edge-center point for alignment
 172  
 173  @property TC
 174  @type String
 175  @value 'tc'
 176  @static
 177  **/
 178  PositionAlign.TC = 'tc';
 179  
 180  /**
 181  Constant used to specify the right edge, center point for alignment
 182  
 183  @property RC
 184  @type String
 185  @value 'rc'
 186  @static
 187  **/
 188  PositionAlign.RC = 'rc';
 189  
 190  /**
 191  Constant used to specify the bottom edge, center point for alignment
 192  
 193  @property BC
 194  @type String
 195  @value 'bc'
 196  @static
 197  **/
 198  PositionAlign.BC = 'bc';
 199  
 200  /**
 201  Constant used to specify the left edge, center point for alignment
 202  
 203  @property LC
 204  @type String
 205  @value 'lc'
 206  @static
 207  **/
 208  PositionAlign.LC = 'lc';
 209  
 210  /**
 211  Constant used to specify the center of widget/node/viewport for alignment
 212  
 213  @property CC
 214  @type String
 215  @value 'cc'
 216  @static
 217  */
 218  PositionAlign.CC = 'cc';
 219  
 220  PositionAlign.prototype = {
 221      // -- Protected Properties -------------------------------------------------
 222  
 223  
 224      initializer : function() {
 225          if (!this._posNode) {
 226              Y.error('WidgetPosition needs to be added to the Widget, ' +
 227                  'before WidgetPositionAlign is added');
 228          }
 229  
 230          Y.after(this._bindUIPosAlign, this, 'bindUI');
 231          Y.after(this._syncUIPosAlign, this, 'syncUI');
 232      },
 233  
 234      /**
 235      Holds the alignment-syncing event handles.
 236  
 237      @property _posAlignUIHandles
 238      @type Array
 239      @default null
 240      @protected
 241      **/
 242      _posAlignUIHandles: null,
 243  
 244      // -- Lifecycle Methods ----------------------------------------------------
 245  
 246      destructor: function () {
 247          this._detachPosAlignUIHandles();
 248      },
 249  
 250      /**
 251      Bind event listeners responsible for updating the UI state in response to
 252      the widget's position-align related state changes.
 253  
 254      This method is invoked after `bindUI` has been invoked for the `Widget`
 255      class using the AOP infrastructure.
 256  
 257      @method _bindUIPosAlign
 258      @protected
 259      **/
 260      _bindUIPosAlign: function () {
 261          this.after('alignChange', this._afterAlignChange);
 262          this.after('alignOnChange', this._afterAlignOnChange);
 263          this.after('visibleChange', this._syncUIPosAlign);
 264      },
 265  
 266      /**
 267      Synchronizes the current `align` Attribute value to the DOM.
 268  
 269      This method is invoked after `syncUI` has been invoked for the `Widget`
 270      class using the AOP infrastructure.
 271  
 272      @method _syncUIPosAlign
 273      @protected
 274      **/
 275      _syncUIPosAlign: function () {
 276          var align = this.get(ALIGN);
 277  
 278          this._uiSetVisiblePosAlign(this.get(VISIBLE));
 279  
 280          if (align) {
 281              this._uiSetAlign(align.node, align.points);
 282          }
 283      },
 284  
 285      // -- Public Methods -------------------------------------------------------
 286  
 287      /**
 288      Aligns this widget to the provided `Node` (or viewport) using the provided
 289      points. This method can be invoked with no arguments which will cause the
 290      widget's current `align` Attribute value to be synced to the DOM.
 291  
 292      @example Aligning to the top-left corner of the `<body>`:
 293  
 294          myWidget.align('body',
 295              [Y.WidgetPositionAlign.TL, Y.WidgetPositionAlign.TR]);
 296  
 297      @method align
 298      @param {Node|String|null} [node] A reference (or selector String) for the
 299        `Node` which with the widget is to be aligned. If null is passed in, the
 300        widget will be aligned with the viewport.
 301      @param {Array[2]} [points] A two item array specifying the points on the
 302        widget and `Node`/viewport which will to be aligned. The first entry is
 303        the point on the widget, and the second entry is the point on the
 304        `Node`/viewport. Valid point references are defined as static constants on
 305        the `WidgetPositionAlign` extension.
 306      @chainable
 307      **/
 308      align: function (node, points) {
 309          if (arguments.length) {
 310              // Set the `align` Attribute.
 311              this.set(ALIGN, {
 312                  node  : node,
 313                  points: points
 314              });
 315          } else {
 316              // Sync the current `align` Attribute value to the DOM.
 317              this._syncUIPosAlign();
 318          }
 319  
 320          return this;
 321      },
 322  
 323      /**
 324      Centers the widget in the viewport, or if a `Node` is passed in, it will
 325      be centered to that `Node`.
 326  
 327      @method centered
 328      @param {Node|String} [node] A `Node` reference or selector String defining
 329        the `Node` which the widget should be centered. If a `Node` is not  passed
 330        in, then the widget will be centered to the viewport.
 331      @chainable
 332      **/
 333      centered: function (node) {
 334          return this.align(node, [PositionAlign.CC, PositionAlign.CC]);
 335      },
 336  
 337      // -- Protected Methods ----------------------------------------------------
 338  
 339      /**
 340      Default setter for `center` Attribute changes. Sets up the appropriate
 341      value, and passes it through the to the align attribute.
 342  
 343      @method _setAlignCenter
 344      @param {Boolean|Node} val The Attribute value being set.
 345      @return {Boolean|Node} the value passed in.
 346      @protected
 347      **/
 348      _setAlignCenter: function (val) {
 349          if (val) {
 350              this.set(ALIGN, {
 351                  node  : val === true ? null : val,
 352                  points: [PositionAlign.CC, PositionAlign.CC]
 353              });
 354          }
 355  
 356          return val;
 357      },
 358  
 359      /**
 360      Updates the UI to reflect the `align` value passed in.
 361  
 362      **Note:** See the `align` Attribute documentation, for the Object structure
 363      expected.
 364  
 365      @method _uiSetAlign
 366      @param {Node|String|null} [node] The node to align to, or null to indicate
 367        the viewport.
 368      @param {Array} points The alignment points.
 369      @protected
 370      **/
 371      _uiSetAlign: function (node, points) {
 372          if ( ! Lang.isArray(points) || points.length !== 2) {
 373              Y.error('align: Invalid Points Arguments');
 374              return;
 375          }
 376  
 377          var nodeRegion = this._getRegion(node),
 378              widgetPoint, nodePoint, xy;
 379  
 380          if ( ! nodeRegion) {
 381              // No-op, nothing to align to.
 382              return;
 383          }
 384  
 385          widgetPoint = points[0];
 386          nodePoint   = points[1];
 387  
 388          // TODO: Optimize KWeight - Would lookup table help?
 389          switch (nodePoint) {
 390          case PositionAlign.TL:
 391              xy = [nodeRegion.left, nodeRegion.top];
 392              break;
 393  
 394          case PositionAlign.TR:
 395              xy = [nodeRegion.right, nodeRegion.top];
 396              break;
 397  
 398          case PositionAlign.BL:
 399              xy = [nodeRegion.left, nodeRegion.bottom];
 400              break;
 401  
 402          case PositionAlign.BR:
 403              xy = [nodeRegion.right, nodeRegion.bottom];
 404              break;
 405  
 406          case PositionAlign.TC:
 407              xy = [
 408                  nodeRegion.left + Math.floor(nodeRegion.width / 2),
 409                  nodeRegion.top
 410              ];
 411              break;
 412  
 413          case PositionAlign.BC:
 414              xy = [
 415                  nodeRegion.left + Math.floor(nodeRegion.width / 2),
 416                  nodeRegion.bottom
 417              ];
 418              break;
 419  
 420          case PositionAlign.LC:
 421              xy = [
 422                  nodeRegion.left,
 423                  nodeRegion.top + Math.floor(nodeRegion.height / 2)
 424              ];
 425              break;
 426  
 427          case PositionAlign.RC:
 428              xy = [
 429                  nodeRegion.right,
 430                  nodeRegion.top + Math.floor(nodeRegion.height / 2)
 431              ];
 432              break;
 433  
 434          case PositionAlign.CC:
 435              xy = [
 436                  nodeRegion.left + Math.floor(nodeRegion.width / 2),
 437                  nodeRegion.top + Math.floor(nodeRegion.height / 2)
 438              ];
 439              break;
 440  
 441          default:
 442              Y.log('align: Invalid Points Arguments', 'info',
 443                  'widget-position-align');
 444              break;
 445  
 446          }
 447  
 448          if (xy) {
 449              this._doAlign(widgetPoint, xy[0], xy[1]);
 450          }
 451      },
 452  
 453      /**
 454      Attaches or detaches alignment-syncing event handlers based on the widget's
 455      `visible` Attribute state.
 456  
 457      @method _uiSetVisiblePosAlign
 458      @param {Boolean} visible The current value of the widget's `visible`
 459        Attribute.
 460      @protected
 461      **/
 462      _uiSetVisiblePosAlign: function (visible) {
 463          if (visible) {
 464              this._attachPosAlignUIHandles();
 465          } else {
 466              this._detachPosAlignUIHandles();
 467          }
 468      },
 469  
 470      /**
 471      Attaches the alignment-syncing event handlers.
 472  
 473      @method _attachPosAlignUIHandles
 474      @protected
 475      **/
 476      _attachPosAlignUIHandles: function () {
 477          if (this._posAlignUIHandles) {
 478              // No-op if we have already setup the event handlers.
 479              return;
 480          }
 481  
 482          var bb        = this.get(BOUNDING_BOX),
 483              syncAlign = Y.bind(this._syncUIPosAlign, this),
 484              handles   = [];
 485  
 486          Y.Array.each(this.get(ALIGN_ON), function (o) {
 487              var event = o.eventName,
 488                  node  = Y.one(o.node) || bb;
 489  
 490              if (event) {
 491                  handles.push(node.on(event, syncAlign));
 492              }
 493          });
 494  
 495          this._posAlignUIHandles = handles;
 496      },
 497  
 498      /**
 499      Detaches the alignment-syncing event handlers.
 500  
 501      @method _detachPosAlignUIHandles
 502      @protected
 503      **/
 504      _detachPosAlignUIHandles: function () {
 505          var handles = this._posAlignUIHandles;
 506          if (handles) {
 507              new Y.EventHandle(handles).detach();
 508              this._posAlignUIHandles = null;
 509          }
 510      },
 511  
 512      // -- Private Methods ------------------------------------------------------
 513  
 514      /**
 515      Helper method, used to align the given point on the widget, with the XY page
 516      coordinates provided.
 517  
 518      @method _doAlign
 519      @param {String} widgetPoint Supported point constant
 520        (e.g. WidgetPositionAlign.TL)
 521      @param {Number} x X page coordinate to align to.
 522      @param {Number} y Y page coordinate to align to.
 523      @private
 524      **/
 525      _doAlign: function (widgetPoint, x, y) {
 526          var widgetNode = this._posNode,
 527              xy;
 528  
 529          switch (widgetPoint) {
 530          case PositionAlign.TL:
 531              xy = [x, y];
 532              break;
 533  
 534          case PositionAlign.TR:
 535              xy = [
 536                  x - widgetNode.get(OFFSET_WIDTH),
 537                  y
 538              ];
 539              break;
 540  
 541          case PositionAlign.BL:
 542              xy = [
 543                  x,
 544                  y - widgetNode.get(OFFSET_HEIGHT)
 545              ];
 546              break;
 547  
 548          case PositionAlign.BR:
 549              xy = [
 550                  x - widgetNode.get(OFFSET_WIDTH),
 551                  y - widgetNode.get(OFFSET_HEIGHT)
 552              ];
 553              break;
 554  
 555          case PositionAlign.TC:
 556              xy = [
 557                  x - (widgetNode.get(OFFSET_WIDTH) / 2),
 558                  y
 559              ];
 560              break;
 561  
 562          case PositionAlign.BC:
 563              xy = [
 564                  x - (widgetNode.get(OFFSET_WIDTH) / 2),
 565                  y - widgetNode.get(OFFSET_HEIGHT)
 566              ];
 567              break;
 568  
 569          case PositionAlign.LC:
 570              xy = [
 571                  x,
 572                  y - (widgetNode.get(OFFSET_HEIGHT) / 2)
 573              ];
 574              break;
 575  
 576          case PositionAlign.RC:
 577              xy = [
 578                  x - widgetNode.get(OFFSET_WIDTH),
 579                  y - (widgetNode.get(OFFSET_HEIGHT) / 2)
 580              ];
 581              break;
 582  
 583          case PositionAlign.CC:
 584              xy = [
 585                  x - (widgetNode.get(OFFSET_WIDTH) / 2),
 586                  y - (widgetNode.get(OFFSET_HEIGHT) / 2)
 587              ];
 588              break;
 589  
 590          default:
 591              Y.log('align: Invalid Points Argument', 'info',
 592                  'widget-position-align');
 593              break;
 594  
 595          }
 596  
 597          if (xy) {
 598              this.move(xy);
 599          }
 600      },
 601  
 602      /**
 603      Returns the region of the passed-in `Node`, or the viewport region if
 604      calling with passing in a `Node`.
 605  
 606      @method _getRegion
 607      @param {Node} [node] The node to get the region of.
 608      @return {Object} The node's region.
 609      @private
 610      **/
 611      _getRegion: function (node) {
 612          var nodeRegion;
 613  
 614          if ( ! node) {
 615              nodeRegion = this._posNode.get(VIEWPORT_REGION);
 616          } else {
 617              node = Y.Node.one(node);
 618              if (node) {
 619                  nodeRegion = node.get(REGION);
 620              }
 621          }
 622  
 623          return nodeRegion;
 624      },
 625  
 626      // -- Protected Event Handlers ---------------------------------------------
 627  
 628      /**
 629      Handles `alignChange` events by updating the UI in response to `align`
 630      Attribute changes.
 631  
 632      @method _afterAlignChange
 633      @param {EventFacade} e
 634      @protected
 635      **/
 636      _afterAlignChange: function (e) {
 637          var align = e.newVal;
 638          if (align) {
 639              this._uiSetAlign(align.node, align.points);
 640          }
 641      },
 642  
 643      /**
 644      Handles `alignOnChange` events by updating the alignment-syncing event
 645      handlers.
 646  
 647      @method _afterAlignOnChange
 648      @param {EventFacade} e
 649      @protected
 650      **/
 651      _afterAlignOnChange: function(e) {
 652          this._detachPosAlignUIHandles();
 653  
 654          if (this.get(VISIBLE)) {
 655              this._attachPosAlignUIHandles();
 656          }
 657      }
 658  };
 659  
 660  Y.WidgetPositionAlign = PositionAlign;
 661  
 662  
 663  }, '3.17.2', {"requires": ["widget-position"]});


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