[ Index ] |
PHP Cross Reference of Unnamed Project |
[Summary view] [Print] [Text view]
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"]});
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Aug 11 10:00:09 2016 | Cross-referenced by PHPXref 0.7.1 |