<!DOCTYPE html>
|
<html>
|
<head>
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
<title>The source code</title>
|
<link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
|
<script type="text/javascript" src="../resources/prettify/prettify.js"></script>
|
<style type="text/css">
|
.highlight { display: block; background-color: #ddd; }
|
</style>
|
<script type="text/javascript">
|
function highlight() {
|
document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
|
}
|
</script>
|
</head>
|
<body onload="prettyPrint(); highlight();">
|
<pre class="prettyprint lang-js"><span id='Ext-resizer-Resizer'>/**
|
</span> * Applies drag handles to an element or component to make it resizable. The drag handles are inserted into the element
|
* (or component's element) and positioned absolute.
|
*
|
* Textarea and img elements will be wrapped with an additional div because these elements do not support child nodes.
|
* The original element can be accessed through the originalTarget property.
|
*
|
* Here is the list of valid resize handles:
|
*
|
* Value Description
|
* ------ -------------------
|
* 'n' north
|
* 's' south
|
* 'e' east
|
* 'w' west
|
* 'nw' northwest
|
* 'sw' southwest
|
* 'se' southeast
|
* 'ne' northeast
|
* 'all' all
|
*
|
* {@img Ext.resizer.Resizer/Ext.resizer.Resizer.png Ext.resizer.Resizer component}
|
*
|
* Here's an example showing the creation of a typical Resizer:
|
*
|
* Ext.create('Ext.resizer.Resizer', {
|
* el: 'elToResize',
|
* handles: 'all',
|
* minWidth: 200,
|
* minHeight: 100,
|
* maxWidth: 500,
|
* maxHeight: 400,
|
* pinned: true
|
* });
|
*/
|
Ext.define('Ext.resizer.Resizer', {
|
mixins: {
|
observable: 'Ext.util.Observable'
|
},
|
uses: ['Ext.resizer.ResizeTracker', 'Ext.Component'],
|
|
alternateClassName: 'Ext.Resizable',
|
|
<span id='Ext-resizer-Resizer-property-handleCls'> handleCls: Ext.baseCSSPrefix + 'resizable-handle',
|
</span><span id='Ext-resizer-Resizer-property-pinnedCls'> pinnedCls: Ext.baseCSSPrefix + 'resizable-pinned',
|
</span><span id='Ext-resizer-Resizer-property-overCls'> overCls: Ext.baseCSSPrefix + 'resizable-over',
|
</span><span id='Ext-resizer-Resizer-property-wrapCls'> wrapCls: Ext.baseCSSPrefix + 'resizable-wrap',
|
</span><span id='Ext-resizer-Resizer-property-delimiterRe'> delimiterRe: /(?:\s*[,;]\s*)|\s+/,
|
</span>
|
<span id='Ext-resizer-Resizer-cfg-dynamic'> /**
|
</span> * @cfg {Boolean} dynamic
|
* Specify as true to update the {@link #target} (Element or {@link Ext.Component Component}) dynamically during
|
* dragging. This is `true` by default, but the {@link Ext.Component Component} class passes `false` when it is
|
* configured as {@link Ext.Component#resizable}.
|
*
|
* If specified as `false`, a proxy element is displayed during the resize operation, and the {@link #target} is
|
* updated on mouseup.
|
*/
|
dynamic: true,
|
|
<span id='Ext-resizer-Resizer-cfg-handles'> /**
|
</span> * @cfg {String} handles
|
* String consisting of the resize handles to display. Defaults to 's e se' for Elements and fixed position
|
* Components. Defaults to 8 point resizing for floating Components (such as Windows). Specify either `'all'` or any
|
* of `'n s e w ne nw se sw'`.
|
*/
|
handles: 's e se',
|
|
<span id='Ext-resizer-Resizer-cfg-height'> /**
|
</span> * @cfg {Number} height
|
* Optional. The height to set target to in pixels
|
*/
|
height : null,
|
|
<span id='Ext-resizer-Resizer-cfg-width'> /**
|
</span> * @cfg {Number} width
|
* Optional. The width to set the target to in pixels
|
*/
|
width : null,
|
|
<span id='Ext-resizer-Resizer-cfg-heightIncrement'> /**
|
</span> * @cfg {Number} heightIncrement
|
* The increment to snap the height resize in pixels.
|
*/
|
heightIncrement : 0,
|
|
<span id='Ext-resizer-Resizer-cfg-widthIncrement'> /**
|
</span> * @cfg {Number} widthIncrement
|
* The increment to snap the width resize in pixels.
|
*/
|
widthIncrement : 0,
|
|
<span id='Ext-resizer-Resizer-cfg-minHeight'> /**
|
</span> * @cfg {Number} minHeight
|
* The minimum height for the element
|
*/
|
minHeight : 20,
|
|
<span id='Ext-resizer-Resizer-cfg-minWidth'> /**
|
</span> * @cfg {Number} minWidth
|
* The minimum width for the element
|
*/
|
minWidth : 20,
|
|
<span id='Ext-resizer-Resizer-cfg-maxHeight'> /**
|
</span> * @cfg {Number} maxHeight
|
* The maximum height for the element
|
*/
|
maxHeight : 10000,
|
|
<span id='Ext-resizer-Resizer-cfg-maxWidth'> /**
|
</span> * @cfg {Number} maxWidth
|
* The maximum width for the element
|
*/
|
maxWidth : 10000,
|
|
<span id='Ext-resizer-Resizer-cfg-pinned'> /**
|
</span> * @cfg {Boolean} pinned
|
* True to ensure that the resize handles are always visible, false indicates resizing by cursor changes only
|
*/
|
pinned: false,
|
|
<span id='Ext-resizer-Resizer-cfg-preserveRatio'> /**
|
</span> * @cfg {Boolean} preserveRatio
|
* True to preserve the original ratio between height and width during resize
|
*/
|
preserveRatio: false,
|
|
<span id='Ext-resizer-Resizer-cfg-transparent'> /**
|
</span> * @cfg {Boolean} transparent
|
* True for transparent handles. This is only applied at config time.
|
*/
|
transparent: false,
|
|
<span id='Ext-resizer-Resizer-cfg-constrainTo'> /**
|
</span> * @cfg {Ext.Element/Ext.util.Region} constrainTo
|
* An element, or a {@link Ext.util.Region Region} into which the resize operation must be constrained.
|
*/
|
|
possiblePositions: {
|
n: 'north',
|
s: 'south',
|
e: 'east',
|
w: 'west',
|
se: 'southeast',
|
sw: 'southwest',
|
nw: 'northwest',
|
ne: 'northeast'
|
},
|
|
<span id='Ext-resizer-Resizer-cfg-target'> /**
|
</span> * @cfg {Ext.Element/Ext.Component} target
|
* The Element or Component to resize.
|
*/
|
|
<span id='Ext-resizer-Resizer-property-el'> /**
|
</span> * @property {Ext.Element} el
|
* Outer element for resizing behavior.
|
*/
|
|
constructor: function(config) {
|
var me = this,
|
target,
|
targetEl,
|
tag,
|
handles = me.handles,
|
handleCls,
|
possibles,
|
len,
|
i = 0,
|
pos,
|
handleEls = [],
|
eastWestStyle, style,
|
box, targetBaseCls,
|
unselectableCls = Ext.dom.Element.unselectableCls;
|
|
me.addEvents(
|
<span id='Ext-resizer-Resizer-event-beforeresize'> /**
|
</span> * @event beforeresize
|
* Fired before resize is allowed. Return false to cancel resize.
|
* @param {Ext.resizer.Resizer} this
|
* @param {Number} width The start width
|
* @param {Number} height The start height
|
* @param {Ext.EventObject} e The mousedown event
|
*/
|
'beforeresize',
|
<span id='Ext-resizer-Resizer-event-resizedrag'> /**
|
</span> * @event resizedrag
|
* Fires during resizing. Return false to cancel resize.
|
* @param {Ext.resizer.Resizer} this
|
* @param {Number} width The new width
|
* @param {Number} height The new height
|
* @param {Ext.EventObject} e The mousedown event
|
*/
|
'resizedrag',
|
<span id='Ext-resizer-Resizer-event-resize'> /**
|
</span> * @event resize
|
* Fired after a resize.
|
* @param {Ext.resizer.Resizer} this
|
* @param {Number} width The new width
|
* @param {Number} height The new height
|
* @param {Ext.EventObject} e The mouseup event
|
*/
|
'resize'
|
);
|
|
if (Ext.isString(config) || Ext.isElement(config) || config.dom) {
|
target = config;
|
config = arguments[1] || {};
|
config.target = target;
|
}
|
// will apply config to this
|
me.mixins.observable.constructor.call(me, config);
|
|
// If target is a Component, ensure that we pull the element out.
|
// Resizer must examine the underlying Element.
|
target = me.target;
|
if (target) {
|
if (target.isComponent) {
|
|
// Resizable Components get a new UI class on them which makes them overflow:visible
|
// if the border width is non-zero and therefore the SASS has embedded the handles
|
// in the borders using -ve position.
|
target.addClsWithUI('resizable');
|
|
me.el = target.getEl();
|
if (target.minWidth) {
|
me.minWidth = target.minWidth;
|
}
|
if (target.minHeight) {
|
me.minHeight = target.minHeight;
|
}
|
if (target.maxWidth) {
|
me.maxWidth = target.maxWidth;
|
}
|
if (target.maxHeight) {
|
me.maxHeight = target.maxHeight;
|
}
|
if (target.floating) {
|
if (!me.hasOwnProperty('handles')) {
|
me.handles = 'n ne e se s sw w nw';
|
}
|
}
|
} else {
|
me.el = me.target = Ext.get(target);
|
}
|
}
|
// Backwards compatibility with Ext3.x's Resizable which used el as a config.
|
else {
|
me.target = me.el = Ext.get(me.el);
|
}
|
|
// Tags like textarea and img cannot
|
// have children and therefore must
|
// be wrapped
|
tag = me.el.dom.tagName.toUpperCase();
|
if (tag == 'TEXTAREA' || tag == 'IMG' || tag == 'TABLE') {
|
<span id='Ext-resizer-Resizer-property-originalTarget'> /**
|
</span> * @property {Ext.Element/Ext.Component} originalTarget
|
* Reference to the original resize target if the element of the original resize target was a
|
* {@link Ext.form.field.Field Field}, or an IMG or a TEXTAREA which must be wrapped in a DIV.
|
*/
|
me.originalTarget = me.target;
|
targetEl = me.el;
|
box = targetEl.getBox();
|
me.target = me.el = me.el.wrap({
|
cls: me.wrapCls,
|
id: me.el.id + '-rzwrap',
|
style: targetEl.getStyles('margin-top', 'margin-bottom')
|
});
|
|
// Transfer originalTarget's positioning+sizing+margins
|
me.el.setPositioning(targetEl.getPositioning());
|
targetEl.clearPositioning();
|
me.el.setBox(box);
|
|
// Position the wrapped element absolute so that it does not stretch the wrapper
|
targetEl.setStyle('position', 'absolute');
|
}
|
|
// Position the element, this enables us to absolute position
|
// the handles within this.el
|
me.el.position();
|
if (me.pinned) {
|
me.el.addCls(me.pinnedCls);
|
}
|
|
<span id='Ext-resizer-Resizer-property-resizeTracker'> /**
|
</span> * @property {Ext.resizer.ResizeTracker} resizeTracker
|
*/
|
me.resizeTracker = new Ext.resizer.ResizeTracker({
|
disabled: me.disabled,
|
target: me.target,
|
constrainTo: me.constrainTo,
|
overCls: me.overCls,
|
throttle: me.throttle,
|
originalTarget: me.originalTarget,
|
delegate: '.' + me.handleCls,
|
dynamic: me.dynamic,
|
preserveRatio: me.preserveRatio,
|
heightIncrement: me.heightIncrement,
|
widthIncrement: me.widthIncrement,
|
minHeight: me.minHeight,
|
maxHeight: me.maxHeight,
|
minWidth: me.minWidth,
|
maxWidth: me.maxWidth
|
});
|
|
// Relay the ResizeTracker's superclass events as our own resize events
|
me.resizeTracker.on({
|
mousedown: me.onBeforeResize,
|
drag: me.onResize,
|
dragend: me.onResizeEnd,
|
scope: me
|
});
|
|
if (me.handles == 'all') {
|
me.handles = 'n s e w ne nw se sw';
|
}
|
|
handles = me.handles = me.handles.split(me.delimiterRe);
|
possibles = me.possiblePositions;
|
len = handles.length;
|
|
handleCls = me.handleCls + ' ' + me.handleCls + '-{0}';
|
if (me.target.isComponent) {
|
targetBaseCls = me.target.baseCls
|
handleCls += ' ' + targetBaseCls + '-handle ' + targetBaseCls + '-handle-{0}';
|
if (Ext.supports.CSS3BorderRadius) {
|
handleCls += ' ' + targetBaseCls + '-handle-{0}-br';
|
}
|
}
|
|
// Needs heighting on IE6!
|
eastWestStyle = Ext.isIE6 ? ' style="height:' + me.el.getHeight() + 'px"' : '';
|
|
for (; i < len; i++){
|
// if specified and possible, create
|
if (handles[i] && possibles[handles[i]]) {
|
pos = possibles[handles[i]];
|
if (pos === 'east' || pos === 'west') {
|
style = eastWestStyle;
|
} else {
|
style = '';
|
}
|
|
handleEls.push(
|
'<div id="', me.el.id, '-', pos, '-handle"',
|
' class="', Ext.String.format(handleCls, pos), ' ', unselectableCls, '"',
|
' unselectable="on"',
|
style,
|
'></div>'
|
);
|
}
|
}
|
Ext.DomHelper.append(me.el, handleEls.join(''));
|
|
// store a reference to each handle element in this.east, this.west, etc
|
for (i = 0; i < len; i++){
|
// if specified and possible, create
|
if (handles[i] && possibles[handles[i]]) {
|
pos = possibles[handles[i]];
|
me[pos] = me.el.getById(me.el.id + '-' + pos + '-handle');
|
me[pos].region = pos;
|
|
if (me.transparent) {
|
me[pos].setOpacity(0);
|
}
|
}
|
}
|
|
// Constrain within configured maxima
|
if (Ext.isNumber(me.width)) {
|
me.width = Ext.Number.constrain(me.width, me.minWidth, me.maxWidth);
|
}
|
if (Ext.isNumber(me.height)) {
|
me.height = Ext.Number.constrain(me.height, me.minHeight, me.maxHeight);
|
}
|
|
// Size the target (and originalTarget)
|
if (me.width !== null || me.height !== null) {
|
if (me.originalTarget) {
|
me.originalTarget.setWidth(me.width);
|
me.originalTarget.setHeight(me.height);
|
}
|
me.resizeTo(me.width, me.height);
|
}
|
|
me.forceHandlesHeight();
|
},
|
|
<span id='Ext-resizer-Resizer-method-disable'> disable: function() {
|
</span> this.resizeTracker.disable();
|
},
|
|
<span id='Ext-resizer-Resizer-method-enable'> enable: function() {
|
</span> this.resizeTracker.enable();
|
},
|
|
<span id='Ext-resizer-Resizer-method-onBeforeResize'> /**
|
</span> * @private Relay the Tracker's mousedown event as beforeresize
|
* @param tracker The Resizer
|
* @param e The Event
|
*/
|
onBeforeResize: function(tracker, e) {
|
var box = this.el.getBox();
|
return this.fireEvent('beforeresize', this, box.width, box.height, e);
|
},
|
|
<span id='Ext-resizer-Resizer-method-onResize'> /**
|
</span> * @private Relay the Tracker's drag event as resizedrag
|
* @param tracker The Resizer
|
* @param e The Event
|
*/
|
onResize: function(tracker, e) {
|
var me = this,
|
box = me.el.getBox();
|
|
me.forceHandlesHeight();
|
return me.fireEvent('resizedrag', me, box.width, box.height, e);
|
},
|
|
<span id='Ext-resizer-Resizer-method-onResizeEnd'> /**
|
</span> * @private Relay the Tracker's dragend event as resize
|
* @param tracker The Resizer
|
* @param e The Event
|
*/
|
onResizeEnd: function(tracker, e) {
|
var me = this,
|
box = me.el.getBox();
|
|
me.forceHandlesHeight();
|
return me.fireEvent('resize', me, box.width, box.height, e);
|
},
|
|
<span id='Ext-resizer-Resizer-method-resizeTo'> /**
|
</span> * Perform a manual resize and fires the 'resize' event.
|
* @param {Number} width
|
* @param {Number} height
|
*/
|
resizeTo : function(width, height) {
|
var me = this;
|
me.target.setSize(width, height);
|
me.fireEvent('resize', me, width, height, null);
|
},
|
|
<span id='Ext-resizer-Resizer-method-getEl'> /**
|
</span> * Returns the element that was configured with the el or target config property. If a component was configured with
|
* the target property then this will return the element of this component.
|
*
|
* Textarea and img elements will be wrapped with an additional div because these elements do not support child
|
* nodes. The original element can be accessed through the originalTarget property.
|
* @return {Ext.Element} element
|
*/
|
getEl : function() {
|
return this.el;
|
},
|
|
<span id='Ext-resizer-Resizer-method-getTarget'> /**
|
</span> * Returns the element or component that was configured with the target config property.
|
*
|
* Textarea and img elements will be wrapped with an additional div because these elements do not support child
|
* nodes. The original element can be accessed through the originalTarget property.
|
* @return {Ext.Element/Ext.Component}
|
*/
|
getTarget: function() {
|
return this.target;
|
},
|
|
<span id='Ext-resizer-Resizer-method-destroy'> destroy: function() {
|
</span> var me = this,
|
i,
|
handles = me.handles,
|
len = handles.length,
|
positions = me.possiblePositions,
|
handle;
|
|
me.resizeTracker.destroy();
|
for (i = 0; i < len; i++) {
|
if (handle = me[positions[handles[i]]]) {
|
handle.remove();
|
}
|
}
|
},
|
|
<span id='Ext-resizer-Resizer-method-forceHandlesHeight'> /**
|
</span> * @private
|
* Fix IE6 handle height issue.
|
*/
|
forceHandlesHeight : function() {
|
var me = this,
|
handle;
|
if (Ext.isIE6) {
|
handle = me.east;
|
if (handle) {
|
handle.setHeight(me.el.getHeight());
|
}
|
handle = me.west;
|
if (handle) {
|
handle.setHeight(me.el.getHeight());
|
}
|
me.el.repaint();
|
}
|
}
|
});
|
</pre>
|
</body>
|
</html>
|