AutorÃa | Ultima modificación | Ver Log |
YUI.add('resize-constrain', function (Y, NAME) {var Lang = Y.Lang,isBoolean = Lang.isBoolean,isNumber = Lang.isNumber,isString = Lang.isString,capitalize = Y.Resize.capitalize,isNode = function(v) {return (v instanceof Y.Node);},toNumber = function(num) {return parseFloat(num) || 0;},BORDER_BOTTOM_WIDTH = 'borderBottomWidth',BORDER_LEFT_WIDTH = 'borderLeftWidth',BORDER_RIGHT_WIDTH = 'borderRightWidth',BORDER_TOP_WIDTH = 'borderTopWidth',BORDER = 'border',BOTTOM = 'bottom',CON = 'con',CONSTRAIN = 'constrain',HOST = 'host',LEFT = 'left',MAX_HEIGHT = 'maxHeight',MAX_WIDTH = 'maxWidth',MIN_HEIGHT = 'minHeight',MIN_WIDTH = 'minWidth',NODE = 'node',OFFSET_HEIGHT = 'offsetHeight',OFFSET_WIDTH = 'offsetWidth',PRESEVE_RATIO = 'preserveRatio',REGION = 'region',RESIZE_CONTRAINED = 'resizeConstrained',RIGHT = 'right',TICK_X = 'tickX',TICK_Y = 'tickY',TOP = 'top',WIDTH = 'width',VIEW = 'view',VIEWPORT_REGION = 'viewportRegion';/**A Resize plugin that will attempt to constrain the resize node to the boundaries.@module resize@submodule resize-contrain@class ResizeConstrained@param config {Object} Object literal specifying widget configuration properties.@constructor@extends Plugin.Base@namespace Plugin*/function ResizeConstrained() {ResizeConstrained.superclass.constructor.apply(this, arguments);}Y.mix(ResizeConstrained, {NAME: RESIZE_CONTRAINED,NS: CON,ATTRS: {/*** Will attempt to constrain the resize node to the boundaries. Arguments:<br>* 'view': Contrain to Viewport<br>* '#selector_string': Constrain to this node<br>* '{Region Object}': An Object Literal containing a valid region (top, right, bottom, left) of page positions** @attribute constrain* @type {String|Object|Node}*/constrain: {setter: function(v) {if (v && (isNode(v) || isString(v) || v.nodeType)) {v = Y.one(v);}return v;}},/*** The minimum height of the element** @attribute minHeight* @default 15* @type Number*/minHeight: {value: 15,validator: isNumber},/*** The minimum width of the element** @attribute minWidth* @default 15* @type Number*/minWidth: {value: 15,validator: isNumber},/*** The maximum height of the element** @attribute maxHeight* @default Infinity* @type Number*/maxHeight: {value: Infinity,validator: isNumber},/*** The maximum width of the element** @attribute maxWidth* @default Infinity* @type Number*/maxWidth: {value: Infinity,validator: isNumber},/*** Maintain the element's ratio when resizing.** @attribute preserveRatio* @default false* @type boolean*/preserveRatio: {value: false,validator: isBoolean},/*** The number of x ticks to span the resize to.** @attribute tickX* @default false* @type Number | false*/tickX: {value: false},/*** The number of y ticks to span the resize to.** @attribute tickY* @default false* @type Number | false*/tickY: {value: false}}});Y.extend(ResizeConstrained, Y.Plugin.Base, {/*** Stores the <code>constrain</code>* surrounding information retrieved from* <a href="Resize.html#method__getBoxSurroundingInfo">_getBoxSurroundingInfo</a>.** @property constrainSurrounding* @type Object* @default null*/constrainSurrounding: null,initializer: function() {var instance = this,host = instance.get(HOST);host.delegate.dd.plug(Y.Plugin.DDConstrained,{tickX: instance.get(TICK_X),tickY: instance.get(TICK_Y)});host.after('resize:align', Y.bind(instance._handleResizeAlignEvent, instance));host.on('resize:start', Y.bind(instance._handleResizeStartEvent, instance));},/*** Helper method to update the current values on* <a href="Resize.html#property_info">info</a> to respect the* constrain node.** @method _checkConstrain* @param {String} axis 'top' or 'left'* @param {String} axisConstrain 'bottom' or 'right'* @param {String} offset 'offsetHeight' or 'offsetWidth'* @protected*/_checkConstrain: function(axis, axisConstrain, offset) {var instance = this,point1,point1Constrain,point2,point2Constrain,host = instance.get(HOST),info = host.info,constrainBorders = instance.constrainSurrounding.border,region = instance._getConstrainRegion();if (region) {point1 = info[axis] + info[offset];point1Constrain = region[axisConstrain] - toNumber(constrainBorders[capitalize(BORDER, axisConstrain, WIDTH)]);if (point1 >= point1Constrain) {info[offset] -= (point1 - point1Constrain);}point2 = info[axis];point2Constrain = region[axis] + toNumber(constrainBorders[capitalize(BORDER, axis, WIDTH)]);if (point2 <= point2Constrain) {info[axis] += (point2Constrain - point2);info[offset] -= (point2Constrain - point2);}}},/*** Update the current values on <a href="Resize.html#property_info">info</a>* to respect the maxHeight and minHeight.** @method _checkHeight* @protected*/_checkHeight: function() {var instance = this,host = instance.get(HOST),info = host.info,maxHeight = (instance.get(MAX_HEIGHT) + host.totalVSurrounding),minHeight = (instance.get(MIN_HEIGHT) + host.totalVSurrounding);instance._checkConstrain(TOP, BOTTOM, OFFSET_HEIGHT);if (info.offsetHeight > maxHeight) {host._checkSize(OFFSET_HEIGHT, maxHeight);}if (info.offsetHeight < minHeight) {host._checkSize(OFFSET_HEIGHT, minHeight);}},/*** Update the current values on <a href="Resize.html#property_info">info</a>* calculating the correct ratio for the other values.** @method _checkRatio* @protected*/_checkRatio: function() {var instance = this,host = instance.get(HOST),info = host.info,originalInfo = host.originalInfo,oWidth = originalInfo.offsetWidth,oHeight = originalInfo.offsetHeight,oTop = originalInfo.top,oLeft = originalInfo.left,oBottom = originalInfo.bottom,oRight = originalInfo.right,// wRatio/hRatio functions keep the ratio information always synced with the current info information// RETURN: percentage how much width/height has changed from the original width/heightwRatio = function() {return (info.offsetWidth/oWidth);},hRatio = function() {return (info.offsetHeight/oHeight);},isClosestToHeight = host.changeHeightHandles,bottomDiff,constrainBorders,constrainRegion,leftDiff,rightDiff,topDiff;// check whether the resizable node is closest to height or notif (instance.get(CONSTRAIN) && host.changeHeightHandles && host.changeWidthHandles) {constrainRegion = instance._getConstrainRegion();constrainBorders = instance.constrainSurrounding.border;bottomDiff = (constrainRegion.bottom - toNumber(constrainBorders[BORDER_BOTTOM_WIDTH])) - oBottom;leftDiff = oLeft - (constrainRegion.left + toNumber(constrainBorders[BORDER_LEFT_WIDTH]));rightDiff = (constrainRegion.right - toNumber(constrainBorders[BORDER_RIGHT_WIDTH])) - oRight;topDiff = oTop - (constrainRegion.top + toNumber(constrainBorders[BORDER_TOP_WIDTH]));if (host.changeLeftHandles && host.changeTopHandles) {isClosestToHeight = (topDiff < leftDiff);}else if (host.changeLeftHandles) {isClosestToHeight = (bottomDiff < leftDiff);}else if (host.changeTopHandles) {isClosestToHeight = (topDiff < rightDiff);}else {isClosestToHeight = (bottomDiff < rightDiff);}}// when the height of the resizable element touch the border of the constrain first// force the offsetWidth to be calculated based on the height ratioif (isClosestToHeight) {info.offsetWidth = oWidth*hRatio();instance._checkWidth();info.offsetHeight = oHeight*wRatio();}else {info.offsetHeight = oHeight*wRatio();instance._checkHeight();info.offsetWidth = oWidth*hRatio();}// fixing the top on handles which are able to change top// the idea here is change the top based on how much the height has changed instead of follow the dyif (host.changeTopHandles) {info.top = oTop + (oHeight - info.offsetHeight);}// fixing the left on handles which are able to change left// the idea here is change the left based on how much the width has changed instead of follow the dxif (host.changeLeftHandles) {info.left = oLeft + (oWidth - info.offsetWidth);}// rounding values to avoid pixel jumpingsY.each(info, function(value, key) {if (isNumber(value)) {info[key] = Math.round(value);}});},/*** Check whether the resizable node is inside the constrain region.** @method _checkRegion* @protected* @return {boolean}*/_checkRegion: function() {var instance = this,host = instance.get(HOST),region = instance._getConstrainRegion();return Y.DOM.inRegion(null, region, true, host.info);},/*** Update the current values on <a href="Resize.html#property_info">info</a>* to respect the maxWidth and minWidth.** @method _checkWidth* @protected*/_checkWidth: function() {var instance = this,host = instance.get(HOST),info = host.info,maxWidth = (instance.get(MAX_WIDTH) + host.totalHSurrounding),minWidth = (instance.get(MIN_WIDTH) + host.totalHSurrounding);instance._checkConstrain(LEFT, RIGHT, OFFSET_WIDTH);if (info.offsetWidth < minWidth) {host._checkSize(OFFSET_WIDTH, minWidth);}if (info.offsetWidth > maxWidth) {host._checkSize(OFFSET_WIDTH, maxWidth);}},/*** Get the constrain region based on the <code>constrain</code>* attribute.** @method _getConstrainRegion* @protected* @return {Object Region}*/_getConstrainRegion: function() {var instance = this,host = instance.get(HOST),node = host.get(NODE),constrain = instance.get(CONSTRAIN),region = null;if (constrain) {if (constrain === VIEW) {region = node.get(VIEWPORT_REGION);}else if (isNode(constrain)) {region = constrain.get(REGION);}else {region = constrain;}}return region;},_handleResizeAlignEvent: function() {var instance = this,host = instance.get(HOST);// check the max/min height and locking top when these values are reachinstance._checkHeight();// check the max/min width and locking left when these values are reachinstance._checkWidth();// calculating the ratio, for proportionally resizingif (instance.get(PRESEVE_RATIO)) {instance._checkRatio();}if (instance.get(CONSTRAIN) && !instance._checkRegion()) {host.info = host.lastInfo;}},_handleResizeStartEvent: function() {var instance = this,constrain = instance.get(CONSTRAIN),host = instance.get(HOST);instance.constrainSurrounding = host._getBoxSurroundingInfo(constrain);}});Y.namespace('Plugin');Y.Plugin.ResizeConstrained = ResizeConstrained;}, '3.18.1', {"requires": ["plugin", "resize-base"]});