Version 3.17.2

APIs

  • Begin typing in the search box above to see results.
Show:

File: widget-position-align/js/Widget-PositionAlign.js

/**
Provides extended/advanced XY positioning support for Widgets, through an
extension.
It builds on top of the `widget-position` module, to provide alignment and
centering support. Future releases aim to add constrained and fixed positioning
support.
@module widget-position-align
**/
var Lang = Y.Lang,
 ALIGN = 'align',
 ALIGN_ON = 'alignOn',
 VISIBLE = 'visible',
 BOUNDING_BOX = 'boundingBox',
 OFFSET_WIDTH = 'offsetWidth',
 OFFSET_HEIGHT = 'offsetHeight',
 REGION = 'region',
 VIEWPORT_REGION = 'viewportRegion';
/**
Widget extension, which can be used to add extended XY positioning support to
the base Widget class, through the `Base.create` method.
**Note:** This extension requires that the `WidgetPosition` extension be added
to the Widget (before `WidgetPositionAlign`, if part of the same extension list
passed to `Base.build`).
@class WidgetPositionAlign
@param {Object} config User configuration object.
@constructor
**/
function PositionAlign (config) {}
PositionAlign.ATTRS = {
 /**
 The alignment configuration for this widget.
 The `align` attribute is used to align a reference point on the widget, with
 the reference point on another `Node`, or the viewport. The object which
 `align` expects has the following properties:
 * __`node`__: The `Node` to which the widget is to be aligned. If set to
 `null`, or not provided, the widget is aligned to the viewport.
 * __`points`__: A two element Array, defining the two points on the widget
 and `Node`/viewport which are to be aligned. The first element is the
 point on the widget, and the second element is the point on the
 `Node`/viewport. Supported alignment points are defined as static
 properties on `WidgetPositionAlign`.
 @example Aligns the top-right corner of the widget with the top-left corner
 of the viewport:
 myWidget.set('align', {
 points: [Y.WidgetPositionAlign.TR, Y.WidgetPositionAlign.TL]
 });
 @attribute align
 @type Object
 @default null
 **/
 align: {
 value: null
 },
 /**
 A convenience Attribute, which can be used as a shortcut for the `align`
 Attribute.
 If set to `true`, the widget is centered in the viewport. If set to a `Node`
 reference or valid selector String, the widget will be centered within the
 `Node`. If set to `false`, no center positioning is applied.
 @attribute centered
 @type Boolean|Node
 @default false
 **/
 centered: {
 setter : '_setAlignCenter',
 lazyAdd:false,
 value :false
 },
 /**
 An Array of Objects corresponding to the `Node`s and events that will cause
 the alignment of this widget to be synced to the DOM.
 The `alignOn` Attribute is expected to be an Array of Objects with the
 following properties:
 * __`eventName`__: The String event name to listen for.
 * __`node`__: The optional `Node` that will fire the event, it can be a
 `Node` reference or a selector String. This will default to the widget's
 `boundingBox`.
 @example Sync this widget's alignment on window resize:
 myWidget.set('alignOn', [
 {
 node : Y.one('win'),
 eventName: 'resize'
 }
 ]);
 @attribute alignOn
 @type Array
 @default []
 **/
 alignOn: {
 value : [],
 validator: Y.Lang.isArray
 }
};
/**
Constant used to specify the top-left corner for alignment
@property TL
@type String
@value 'tl'
@static
**/
PositionAlign.TL = 'tl';
/**
Constant used to specify the top-right corner for alignment
@property TR
@type String
@value 'tr'
@static
**/
PositionAlign.TR = 'tr';
/**
Constant used to specify the bottom-left corner for alignment
@property BL
@type String
@value 'bl'
@static
**/
PositionAlign.BL = 'bl';
/**
Constant used to specify the bottom-right corner for alignment
@property BR
@type String
@value 'br'
@static
**/
PositionAlign.BR = 'br';
/**
Constant used to specify the top edge-center point for alignment
@property TC
@type String
@value 'tc'
@static
**/
PositionAlign.TC = 'tc';
/**
Constant used to specify the right edge, center point for alignment
@property RC
@type String
@value 'rc'
@static
**/
PositionAlign.RC = 'rc';
/**
Constant used to specify the bottom edge, center point for alignment
@property BC
@type String
@value 'bc'
@static
**/
PositionAlign.BC = 'bc';
/**
Constant used to specify the left edge, center point for alignment
@property LC
@type String
@value 'lc'
@static
**/
PositionAlign.LC = 'lc';
/**
Constant used to specify the center of widget/node/viewport for alignment
@property CC
@type String
@value 'cc'
@static
*/
PositionAlign.CC = 'cc';
PositionAlign.prototype = {
 // -- Protected Properties -------------------------------------------------
 initializer : function() {
 if (!this._posNode) {
 Y.error('WidgetPosition needs to be added to the Widget, ' +
 'before WidgetPositionAlign is added');
 }
 Y.after(this._bindUIPosAlign, this, 'bindUI');
 Y.after(this._syncUIPosAlign, this, 'syncUI');
 },
 /**
 Holds the alignment-syncing event handles.
 @property _posAlignUIHandles
 @type Array
 @default null
 @protected
 **/
 _posAlignUIHandles: null,
 // -- Lifecycle Methods ----------------------------------------------------
 destructor: function () {
 this._detachPosAlignUIHandles();
 },
 /**
 Bind event listeners responsible for updating the UI state in response to
 the widget's position-align related state changes.
 This method is invoked after `bindUI` has been invoked for the `Widget`
 class using the AOP infrastructure.
 @method _bindUIPosAlign
 @protected
 **/
 _bindUIPosAlign: function () {
 this.after('alignChange', this._afterAlignChange);
 this.after('alignOnChange', this._afterAlignOnChange);
 this.after('visibleChange', this._syncUIPosAlign);
 },
 /**
 Synchronizes the current `align` Attribute value to the DOM.
 This method is invoked after `syncUI` has been invoked for the `Widget`
 class using the AOP infrastructure.
 @method _syncUIPosAlign
 @protected
 **/
 _syncUIPosAlign: function () {
 var align = this.get(ALIGN);
 this._uiSetVisiblePosAlign(this.get(VISIBLE));
 if (align) {
 this._uiSetAlign(align.node, align.points);
 }
 },
 // -- Public Methods -------------------------------------------------------
 /**
 Aligns this widget to the provided `Node` (or viewport) using the provided
 points. This method can be invoked with no arguments which will cause the
 widget's current `align` Attribute value to be synced to the DOM.
 @example Aligning to the top-left corner of the `<body>`:
 myWidget.align('body',
 [Y.WidgetPositionAlign.TL, Y.WidgetPositionAlign.TR]);
 @method align
 @param {Node|String|null} [node] A reference (or selector String) for the
 `Node` which with the widget is to be aligned. If null is passed in, the
 widget will be aligned with the viewport.
 @param {Array[2]} [points] A two item array specifying the points on the
 widget and `Node`/viewport which will to be aligned. The first entry is
 the point on the widget, and the second entry is the point on the
 `Node`/viewport. Valid point references are defined as static constants on
 the `WidgetPositionAlign` extension.
 @chainable
 **/
 align: function (node, points) {
 if (arguments.length) {
 // Set the `align` Attribute.
 this.set(ALIGN, {
 node : node,
 points: points
 });
 } else {
 // Sync the current `align` Attribute value to the DOM.
 this._syncUIPosAlign();
 }
 return this;
 },
 /**
 Centers the widget in the viewport, or if a `Node` is passed in, it will
 be centered to that `Node`.
 @method centered
 @param {Node|String} [node] A `Node` reference or selector String defining
 the `Node` which the widget should be centered. If a `Node` is not passed
 in, then the widget will be centered to the viewport.
 @chainable
 **/
 centered: function (node) {
 return this.align(node, [PositionAlign.CC, PositionAlign.CC]);
 },
 // -- Protected Methods ----------------------------------------------------
 /**
 Default setter for `center` Attribute changes. Sets up the appropriate
 value, and passes it through the to the align attribute.
 @method _setAlignCenter
 @param {Boolean|Node} val The Attribute value being set.
 @return {Boolean|Node} the value passed in.
 @protected
 **/
 _setAlignCenter: function (val) {
 if (val) {
 this.set(ALIGN, {
 node : val === true ? null : val,
 points: [PositionAlign.CC, PositionAlign.CC]
 });
 }
 return val;
 },
 /**
 Updates the UI to reflect the `align` value passed in.
 **Note:** See the `align` Attribute documentation, for the Object structure
 expected.
 @method _uiSetAlign
 @param {Node|String|null} [node] The node to align to, or null to indicate
 the viewport.
 @param {Array} points The alignment points.
 @protected
 **/
 _uiSetAlign: function (node, points) {
 if ( ! Lang.isArray(points) || points.length !== 2) {
 Y.error('align: Invalid Points Arguments');
 return;
 }
 var nodeRegion = this._getRegion(node),
 widgetPoint, nodePoint, xy;
 if ( ! nodeRegion) {
 // No-op, nothing to align to.
 return;
 }
 widgetPoint = points[0];
 nodePoint = points[1];
 // TODO: Optimize KWeight - Would lookup table help?
 switch (nodePoint) {
 case PositionAlign.TL:
 xy = [nodeRegion.left, nodeRegion.top];
 break;
 case PositionAlign.TR:
 xy = [nodeRegion.right, nodeRegion.top];
 break;
 case PositionAlign.BL:
 xy = [nodeRegion.left, nodeRegion.bottom];
 break;
 case PositionAlign.BR:
 xy = [nodeRegion.right, nodeRegion.bottom];
 break;
 case PositionAlign.TC:
 xy = [
 nodeRegion.left + Math.floor(nodeRegion.width / 2),
 nodeRegion.top
 ];
 break;
 case PositionAlign.BC:
 xy = [
 nodeRegion.left + Math.floor(nodeRegion.width / 2),
 nodeRegion.bottom
 ];
 break;
 case PositionAlign.LC:
 xy = [
 nodeRegion.left,
 nodeRegion.top + Math.floor(nodeRegion.height / 2)
 ];
 break;
 case PositionAlign.RC:
 xy = [
 nodeRegion.right,
 nodeRegion.top + Math.floor(nodeRegion.height / 2)
 ];
 break;
 case PositionAlign.CC:
 xy = [
 nodeRegion.left + Math.floor(nodeRegion.width / 2),
 nodeRegion.top + Math.floor(nodeRegion.height / 2)
 ];
 break;
 default:
 Y.log('align: Invalid Points Arguments', 'info',
 'widget-position-align');
 break;
 }
 if (xy) {
 this._doAlign(widgetPoint, xy[0], xy[1]);
 }
 },
 /**
 Attaches or detaches alignment-syncing event handlers based on the widget's
 `visible` Attribute state.
 @method _uiSetVisiblePosAlign
 @param {Boolean} visible The current value of the widget's `visible`
 Attribute.
 @protected
 **/
 _uiSetVisiblePosAlign: function (visible) {
 if (visible) {
 this._attachPosAlignUIHandles();
 } else {
 this._detachPosAlignUIHandles();
 }
 },
 /**
 Attaches the alignment-syncing event handlers.
 @method _attachPosAlignUIHandles
 @protected
 **/
 _attachPosAlignUIHandles: function () {
 if (this._posAlignUIHandles) {
 // No-op if we have already setup the event handlers.
 return;
 }
 var bb = this.get(BOUNDING_BOX),
 syncAlign = Y.bind(this._syncUIPosAlign, this),
 handles = [];
 Y.Array.each(this.get(ALIGN_ON), function (o) {
 var event = o.eventName,
 node = Y.one(o.node) || bb;
 if (event) {
 handles.push(node.on(event, syncAlign));
 }
 });
 this._posAlignUIHandles = handles;
 },
 /**
 Detaches the alignment-syncing event handlers.
 @method _detachPosAlignUIHandles
 @protected
 **/
 _detachPosAlignUIHandles: function () {
 var handles = this._posAlignUIHandles;
 if (handles) {
 new Y.EventHandle(handles).detach();
 this._posAlignUIHandles = null;
 }
 },
 // -- Private Methods ------------------------------------------------------
 /**
 Helper method, used to align the given point on the widget, with the XY page
 coordinates provided.
 @method _doAlign
 @param {String} widgetPoint Supported point constant
 (e.g. WidgetPositionAlign.TL)
 @param {Number} x X page coordinate to align to.
 @param {Number} y Y page coordinate to align to.
 @private
 **/
 _doAlign: function (widgetPoint, x, y) {
 var widgetNode = this._posNode,
 xy;
 switch (widgetPoint) {
 case PositionAlign.TL:
 xy = [x, y];
 break;
 case PositionAlign.TR:
 xy = [
 x - widgetNode.get(OFFSET_WIDTH),
 y
 ];
 break;
 case PositionAlign.BL:
 xy = [
 x,
 y - widgetNode.get(OFFSET_HEIGHT)
 ];
 break;
 case PositionAlign.BR:
 xy = [
 x - widgetNode.get(OFFSET_WIDTH),
 y - widgetNode.get(OFFSET_HEIGHT)
 ];
 break;
 case PositionAlign.TC:
 xy = [
 x - (widgetNode.get(OFFSET_WIDTH) / 2),
 y
 ];
 break;
 case PositionAlign.BC:
 xy = [
 x - (widgetNode.get(OFFSET_WIDTH) / 2),
 y - widgetNode.get(OFFSET_HEIGHT)
 ];
 break;
 case PositionAlign.LC:
 xy = [
 x,
 y - (widgetNode.get(OFFSET_HEIGHT) / 2)
 ];
 break;
 case PositionAlign.RC:
 xy = [
 x - widgetNode.get(OFFSET_WIDTH),
 y - (widgetNode.get(OFFSET_HEIGHT) / 2)
 ];
 break;
 case PositionAlign.CC:
 xy = [
 x - (widgetNode.get(OFFSET_WIDTH) / 2),
 y - (widgetNode.get(OFFSET_HEIGHT) / 2)
 ];
 break;
 default:
 Y.log('align: Invalid Points Argument', 'info',
 'widget-position-align');
 break;
 }
 if (xy) {
 this.move(xy);
 }
 },
 /**
 Returns the region of the passed-in `Node`, or the viewport region if
 calling with passing in a `Node`.
 @method _getRegion
 @param {Node} [node] The node to get the region of.
 @return {Object} The node's region.
 @private
 **/
 _getRegion: function (node) {
 var nodeRegion;
 if ( ! node) {
 nodeRegion = this._posNode.get(VIEWPORT_REGION);
 } else {
 node = Y.Node.one(node);
 if (node) {
 nodeRegion = node.get(REGION);
 }
 }
 return nodeRegion;
 },
 // -- Protected Event Handlers ---------------------------------------------
 /**
 Handles `alignChange` events by updating the UI in response to `align`
 Attribute changes.
 @method _afterAlignChange
 @param {EventFacade} e
 @protected
 **/
 _afterAlignChange: function (e) {
 var align = e.newVal;
 if (align) {
 this._uiSetAlign(align.node, align.points);
 }
 },
 /**
 Handles `alignOnChange` events by updating the alignment-syncing event
 handlers.
 @method _afterAlignOnChange
 @param {EventFacade} e
 @protected
 **/
 _afterAlignOnChange: function(e) {
 this._detachPosAlignUIHandles();
 if (this.get(VISIBLE)) {
 this._attachPosAlignUIHandles();
 }
 }
};
Y.WidgetPositionAlign = PositionAlign;
 

AltStyle によって変換されたページ (->オリジナル) /