0
|
1 /*
|
|
2 Copyright (c) 2009, Yahoo! Inc. All rights reserved.
|
|
3 Code licensed under the BSD License:
|
|
4 http://developer.yahoo.net/yui/license.txt
|
|
5 version: 2.8.0r4
|
|
6 */
|
|
7 /**
|
|
8 * @description <p>Makes an element resizable</p>
|
|
9 * @namespace YAHOO.util
|
|
10 * @requires yahoo, dom, dragdrop, element, event
|
|
11 * @optional animation
|
|
12 * @module resize
|
|
13 */
|
|
14 (function() {
|
|
15 var D = YAHOO.util.Dom,
|
|
16 Event = YAHOO.util.Event,
|
|
17 Lang = YAHOO.lang;
|
|
18
|
|
19 /**
|
|
20 * @constructor
|
|
21 * @class Resize
|
|
22 * @extends YAHOO.util.Element
|
|
23 * @description <p>Makes an element resizable</p>
|
|
24 * @param {String/HTMLElement} el The element to make resizable.
|
|
25 * @param {Object} attrs Object liternal containing configuration parameters.
|
|
26 */
|
|
27
|
|
28 var Resize = function(el, config) {
|
|
29 var oConfig = {
|
|
30 element: el,
|
|
31 attributes: config || {}
|
|
32 };
|
|
33
|
|
34 Resize.superclass.constructor.call(this, oConfig.element, oConfig.attributes);
|
|
35 };
|
|
36
|
|
37 /**
|
|
38 * @private
|
|
39 * @static
|
|
40 * @property _instances
|
|
41 * @description Internal hash table for all resize instances
|
|
42 * @type Object
|
|
43 */
|
|
44 Resize._instances = {};
|
|
45 /**
|
|
46 * @static
|
|
47 * @method getResizeById
|
|
48 * @description Get's a resize object by the HTML id of the element associated with the Resize object.
|
|
49 * @return {Object} The Resize Object
|
|
50 */
|
|
51 Resize.getResizeById = function(id) {
|
|
52 if (Resize._instances[id]) {
|
|
53 return Resize._instances[id];
|
|
54 }
|
|
55 return false;
|
|
56 };
|
|
57
|
|
58 YAHOO.extend(Resize, YAHOO.util.Element, {
|
|
59 /**
|
|
60 * @private
|
|
61 * @property CSS_RESIZE
|
|
62 * @description Base CSS class name
|
|
63 * @type String
|
|
64 */
|
|
65 CSS_RESIZE: 'yui-resize',
|
|
66 /**
|
|
67 * @private
|
|
68 * @property CSS_DRAG
|
|
69 * @description Class name added when dragging is enabled
|
|
70 * @type String
|
|
71 */
|
|
72 CSS_DRAG: 'yui-draggable',
|
|
73 /**
|
|
74 * @private
|
|
75 * @property CSS_HOVER
|
|
76 * @description Class name used for hover only handles
|
|
77 * @type String
|
|
78 */
|
|
79 CSS_HOVER: 'yui-resize-hover',
|
|
80 /**
|
|
81 * @private
|
|
82 * @property CSS_PROXY
|
|
83 * @description Class name given to the proxy element
|
|
84 * @type String
|
|
85 */
|
|
86 CSS_PROXY: 'yui-resize-proxy',
|
|
87 /**
|
|
88 * @private
|
|
89 * @property CSS_WRAP
|
|
90 * @description Class name given to the wrap element
|
|
91 * @type String
|
|
92 */
|
|
93 CSS_WRAP: 'yui-resize-wrap',
|
|
94 /**
|
|
95 * @private
|
|
96 * @property CSS_KNOB
|
|
97 * @description Class name used to make the knob style handles
|
|
98 * @type String
|
|
99 */
|
|
100 CSS_KNOB: 'yui-resize-knob',
|
|
101 /**
|
|
102 * @private
|
|
103 * @property CSS_HIDDEN
|
|
104 * @description Class name given to the wrap element to make all handles hidden
|
|
105 * @type String
|
|
106 */
|
|
107 CSS_HIDDEN: 'yui-resize-hidden',
|
|
108 /**
|
|
109 * @private
|
|
110 * @property CSS_HANDLE
|
|
111 * @description Class name given to all handles, used as a base for single handle names as well.. Handle "t" will get this.CSS_HANDLE + '-t' as well as this.CSS_HANDLE
|
|
112 * @type String
|
|
113 */
|
|
114 CSS_HANDLE: 'yui-resize-handle',
|
|
115 /**
|
|
116 * @private
|
|
117 * @property CSS_STATUS
|
|
118 * @description Class name given to the status element
|
|
119 * @type String
|
|
120 */
|
|
121 CSS_STATUS: 'yui-resize-status',
|
|
122 /**
|
|
123 * @private
|
|
124 * @property CSS_GHOST
|
|
125 * @description Class name given to the wrap element when the ghost property is active
|
|
126 * @type String
|
|
127 */
|
|
128 CSS_GHOST: 'yui-resize-ghost',
|
|
129 /**
|
|
130 * @private
|
|
131 * @property CSS_RESIZING
|
|
132 * @description Class name given to the wrap element when a resize action is taking place.
|
|
133 * @type String
|
|
134 */
|
|
135 CSS_RESIZING: 'yui-resize-resizing',
|
|
136 /**
|
|
137 * @private
|
|
138 * @property _resizeEvent
|
|
139 * @description The mouse event used to resize with
|
|
140 * @type Event
|
|
141 */
|
|
142 _resizeEvent: null,
|
|
143 /**
|
|
144 * @private
|
|
145 * @property dd
|
|
146 * @description The <a href="YAHOO.util.DragDrop.html">YAHOO.util.DragDrop</a> instance used if draggable is true
|
|
147 * @type Object
|
|
148 */
|
|
149 dd: null,
|
|
150 /**
|
|
151 * @private
|
|
152 * @property browser
|
|
153 * @description A copy of the YAHOO.env.ua property
|
|
154 * @type Object
|
|
155 */
|
|
156 browser: YAHOO.env.ua,
|
|
157 /**
|
|
158 * @private
|
|
159 * @property _locked
|
|
160 * @description A flag to show if the resize is locked
|
|
161 * @type Boolean
|
|
162 */
|
|
163 _locked: null,
|
|
164 /**
|
|
165 * @private
|
|
166 * @property _positioned
|
|
167 * @description A flag to show if the element is absolutely positioned
|
|
168 * @type Boolean
|
|
169 */
|
|
170 _positioned: null,
|
|
171 /**
|
|
172 * @private
|
|
173 * @property _dds
|
|
174 * @description An Object containing references to all of the <a href="YAHOO.util.DragDrop.html">YAHOO.util.DragDrop</a> instances used for the resize handles
|
|
175 * @type Object
|
|
176 */
|
|
177 _dds: null,
|
|
178 /**
|
|
179 * @private
|
|
180 * @property _wrap
|
|
181 * @description The HTML reference of the element wrapper
|
|
182 * @type HTMLElement
|
|
183 */
|
|
184 _wrap: null,
|
|
185 /**
|
|
186 * @private
|
|
187 * @property _proxy
|
|
188 * @description The HTML reference of the element proxy
|
|
189 * @type HTMLElement
|
|
190 */
|
|
191 _proxy: null,
|
|
192 /**
|
|
193 * @private
|
|
194 * @property _handles
|
|
195 * @description An object containing references to all of the resize handles.
|
|
196 * @type Object
|
|
197 */
|
|
198 _handles: null,
|
|
199 /**
|
|
200 * @private
|
|
201 * @property _currentHandle
|
|
202 * @description The string identifier of the currently active handle. e.g. 'r', 'br', 'tl'
|
|
203 * @type String
|
|
204 */
|
|
205 _currentHandle: null,
|
|
206 /**
|
|
207 * @private
|
|
208 * @property _currentDD
|
|
209 * @description A link to the currently active DD object
|
|
210 * @type Object
|
|
211 */
|
|
212 _currentDD: null,
|
|
213 /**
|
|
214 * @private
|
|
215 * @property _cache
|
|
216 * @description An lookup table containing key information for the element being resized. e.g. height, width, x position, y position, etc..
|
|
217 * @type Object
|
|
218 */
|
|
219 _cache: null,
|
|
220 /**
|
|
221 * @private
|
|
222 * @property _active
|
|
223 * @description Flag to show if the resize is active. Used for events.
|
|
224 * @type Boolean
|
|
225 */
|
|
226 _active: null,
|
|
227 /**
|
|
228 * @private
|
|
229 * @method _createProxy
|
|
230 * @description Creates the proxy element if the proxy config is true
|
|
231 */
|
|
232 _createProxy: function() {
|
|
233 if (this.get('proxy')) {
|
|
234 this._proxy = document.createElement('div');
|
|
235 this._proxy.className = this.CSS_PROXY;
|
|
236 this._proxy.style.height = this.get('element').clientHeight + 'px';
|
|
237 this._proxy.style.width = this.get('element').clientWidth + 'px';
|
|
238 this._wrap.parentNode.appendChild(this._proxy);
|
|
239 } else {
|
|
240 this.set('animate', false);
|
|
241 }
|
|
242 },
|
|
243 /**
|
|
244 * @private
|
|
245 * @method _createWrap
|
|
246 * @description Creates the wrap element if the wrap config is true. It will auto wrap the following element types: img, textarea, input, iframe, select
|
|
247 */
|
|
248 _createWrap: function() {
|
|
249 this._positioned = false;
|
|
250 //Force wrap for elements that can't have children
|
|
251 if (this.get('wrap') === false) {
|
|
252 switch (this.get('element').tagName.toLowerCase()) {
|
|
253 case 'img':
|
|
254 case 'textarea':
|
|
255 case 'input':
|
|
256 case 'iframe':
|
|
257 case 'select':
|
|
258 this.set('wrap', true);
|
|
259 break;
|
|
260 }
|
|
261 }
|
|
262 if (this.get('wrap') === true) {
|
|
263 this._wrap = document.createElement('div');
|
|
264 this._wrap.id = this.get('element').id + '_wrap';
|
|
265 this._wrap.className = this.CSS_WRAP;
|
|
266 if (this.get('element').tagName.toLowerCase() == 'textarea') {
|
|
267 D.addClass(this._wrap, 'yui-resize-textarea');
|
|
268 }
|
|
269 D.setStyle(this._wrap, 'width', this.get('width') + 'px');
|
|
270 D.setStyle(this._wrap, 'height', this.get('height') + 'px');
|
|
271 D.setStyle(this._wrap, 'z-index', this.getStyle('z-index'));
|
|
272 this.setStyle('z-index', 0);
|
|
273 var pos = D.getStyle(this.get('element'), 'position');
|
|
274 D.setStyle(this._wrap, 'position', ((pos == 'static') ? 'relative' : pos));
|
|
275 D.setStyle(this._wrap, 'top', D.getStyle(this.get('element'), 'top'));
|
|
276 D.setStyle(this._wrap, 'left', D.getStyle(this.get('element'), 'left'));
|
|
277 if (D.getStyle(this.get('element'), 'position') == 'absolute') {
|
|
278 this._positioned = true;
|
|
279 D.setStyle(this.get('element'), 'position', 'relative');
|
|
280 D.setStyle(this.get('element'), 'top', '0');
|
|
281 D.setStyle(this.get('element'), 'left', '0');
|
|
282 }
|
|
283 var par = this.get('element').parentNode;
|
|
284 par.replaceChild(this._wrap, this.get('element'));
|
|
285 this._wrap.appendChild(this.get('element'));
|
|
286 } else {
|
|
287 this._wrap = this.get('element');
|
|
288 if (D.getStyle(this._wrap, 'position') == 'absolute') {
|
|
289 this._positioned = true;
|
|
290 }
|
|
291 }
|
|
292 if (this.get('draggable')) {
|
|
293 this._setupDragDrop();
|
|
294 }
|
|
295 if (this.get('hover')) {
|
|
296 D.addClass(this._wrap, this.CSS_HOVER);
|
|
297 }
|
|
298 if (this.get('knobHandles')) {
|
|
299 D.addClass(this._wrap, this.CSS_KNOB);
|
|
300 }
|
|
301 if (this.get('hiddenHandles')) {
|
|
302 D.addClass(this._wrap, this.CSS_HIDDEN);
|
|
303 }
|
|
304 D.addClass(this._wrap, this.CSS_RESIZE);
|
|
305 },
|
|
306 /**
|
|
307 * @private
|
|
308 * @method _setupDragDrop
|
|
309 * @description Setup the <a href="YAHOO.util.DragDrop.html">YAHOO.util.DragDrop</a> instance on the element
|
|
310 */
|
|
311 _setupDragDrop: function() {
|
|
312 D.addClass(this._wrap, this.CSS_DRAG);
|
|
313 this.dd = new YAHOO.util.DD(this._wrap, this.get('id') + '-resize', { dragOnly: true, useShim: this.get('useShim') });
|
|
314 this.dd.on('dragEvent', function() {
|
|
315 this.fireEvent('dragEvent', arguments);
|
|
316 }, this, true);
|
|
317 },
|
|
318 /**
|
|
319 * @private
|
|
320 * @method _createHandles
|
|
321 * @description Creates the handles as specified in the config
|
|
322 */
|
|
323 _createHandles: function() {
|
|
324 this._handles = {};
|
|
325 this._dds = {};
|
|
326 var h = this.get('handles');
|
|
327 for (var i = 0; i < h.length; i++) {
|
|
328 this._handles[h[i]] = document.createElement('div');
|
|
329 this._handles[h[i]].id = D.generateId(this._handles[h[i]]);
|
|
330 this._handles[h[i]].className = this.CSS_HANDLE + ' ' + this.CSS_HANDLE + '-' + h[i];
|
|
331 var k = document.createElement('div');
|
|
332 k.className = this.CSS_HANDLE + '-inner-' + h[i];
|
|
333 this._handles[h[i]].appendChild(k);
|
|
334 this._wrap.appendChild(this._handles[h[i]]);
|
|
335 Event.on(this._handles[h[i]], 'mouseover', this._handleMouseOver, this, true);
|
|
336 Event.on(this._handles[h[i]], 'mouseout', this._handleMouseOut, this, true);
|
|
337 this._dds[h[i]] = new YAHOO.util.DragDrop(this._handles[h[i]], this.get('id') + '-handle-' + h, { useShim: this.get('useShim') });
|
|
338 this._dds[h[i]].setPadding(15, 15, 15, 15);
|
|
339 this._dds[h[i]].on('startDragEvent', this._handleStartDrag, this._dds[h[i]], this);
|
|
340 this._dds[h[i]].on('mouseDownEvent', this._handleMouseDown, this._dds[h[i]], this);
|
|
341 }
|
|
342 this._status = document.createElement('span');
|
|
343 this._status.className = this.CSS_STATUS;
|
|
344 document.body.insertBefore(this._status, document.body.firstChild);
|
|
345 },
|
|
346 /**
|
|
347 * @private
|
|
348 * @method _ieSelectFix
|
|
349 * @description The function we use as the onselectstart handler when we start a drag in Internet Explorer
|
|
350 */
|
|
351 _ieSelectFix: function() {
|
|
352 return false;
|
|
353 },
|
|
354 /**
|
|
355 * @private
|
|
356 * @property _ieSelectBack
|
|
357 * @description We will hold a copy of the current "onselectstart" method on this property, and reset it after we are done using it.
|
|
358 */
|
|
359 _ieSelectBack: null,
|
|
360 /**
|
|
361 * @private
|
|
362 * @method _setAutoRatio
|
|
363 * @param {Event} ev A mouse event.
|
|
364 * @description This method checks to see if the "autoRatio" config is set. If it is, we will check to see if the "Shift Key" is pressed. If so, we will set the config ratio to true.
|
|
365 */
|
|
366 _setAutoRatio: function(ev) {
|
|
367 if (this.get('autoRatio')) {
|
|
368 if (ev && ev.shiftKey) {
|
|
369 //Shift Pressed
|
|
370 this.set('ratio', true);
|
|
371 } else {
|
|
372 this.set('ratio', this._configs.ratio._initialConfig.value);
|
|
373 }
|
|
374 }
|
|
375 },
|
|
376 /**
|
|
377 * @private
|
|
378 * @method _handleMouseDown
|
|
379 * @param {Event} ev A mouse event.
|
|
380 * @description This method preps the autoRatio on MouseDown.
|
|
381 */
|
|
382 _handleMouseDown: function(ev) {
|
|
383 if (this._locked) {
|
|
384 return false;
|
|
385 }
|
|
386 if (D.getStyle(this._wrap, 'position') == 'absolute') {
|
|
387 this._positioned = true;
|
|
388 }
|
|
389 if (ev) {
|
|
390 this._setAutoRatio(ev);
|
|
391 }
|
|
392 if (this.browser.ie) {
|
|
393 this._ieSelectBack = document.body.onselectstart;
|
|
394 document.body.onselectstart = this._ieSelectFix;
|
|
395 }
|
|
396 },
|
|
397 /**
|
|
398 * @private
|
|
399 * @method _handleMouseOver
|
|
400 * @param {Event} ev A mouse event.
|
|
401 * @description Adds CSS class names to the handles
|
|
402 */
|
|
403 _handleMouseOver: function(ev) {
|
|
404 if (this._locked) {
|
|
405 return false;
|
|
406 }
|
|
407 D.removeClass(this._wrap, this.CSS_RESIZE);
|
|
408
|
|
409 if (this.get('hover')) {
|
|
410 D.removeClass(this._wrap, this.CSS_HOVER);
|
|
411 }
|
|
412 var tar = Event.getTarget(ev);
|
|
413 if (!D.hasClass(tar, this.CSS_HANDLE)) {
|
|
414 tar = tar.parentNode;
|
|
415 }
|
|
416 if (D.hasClass(tar, this.CSS_HANDLE) && !this._active) {
|
|
417 D.addClass(tar, this.CSS_HANDLE + '-active');
|
|
418 for (var i in this._handles) {
|
|
419 if (Lang.hasOwnProperty(this._handles, i)) {
|
|
420 if (this._handles[i] == tar) {
|
|
421 D.addClass(tar, this.CSS_HANDLE + '-' + i + '-active');
|
|
422 break;
|
|
423 }
|
|
424 }
|
|
425 }
|
|
426 }
|
|
427
|
|
428 D.addClass(this._wrap, this.CSS_RESIZE);
|
|
429 },
|
|
430 /**
|
|
431 * @private
|
|
432 * @method _handleMouseOut
|
|
433 * @param {Event} ev A mouse event.
|
|
434 * @description Removes CSS class names to the handles
|
|
435 */
|
|
436 _handleMouseOut: function(ev) {
|
|
437 D.removeClass(this._wrap, this.CSS_RESIZE);
|
|
438 if (this.get('hover') && !this._active) {
|
|
439 D.addClass(this._wrap, this.CSS_HOVER);
|
|
440 }
|
|
441 var tar = Event.getTarget(ev);
|
|
442 if (!D.hasClass(tar, this.CSS_HANDLE)) {
|
|
443 tar = tar.parentNode;
|
|
444 }
|
|
445 if (D.hasClass(tar, this.CSS_HANDLE) && !this._active) {
|
|
446 D.removeClass(tar, this.CSS_HANDLE + '-active');
|
|
447 for (var i in this._handles) {
|
|
448 if (Lang.hasOwnProperty(this._handles, i)) {
|
|
449 if (this._handles[i] == tar) {
|
|
450 D.removeClass(tar, this.CSS_HANDLE + '-' + i + '-active');
|
|
451 break;
|
|
452 }
|
|
453 }
|
|
454 }
|
|
455 }
|
|
456 D.addClass(this._wrap, this.CSS_RESIZE);
|
|
457 },
|
|
458 /**
|
|
459 * @private
|
|
460 * @method _handleStartDrag
|
|
461 * @param {Object} args The args passed from the CustomEvent.
|
|
462 * @param {Object} dd The <a href="YAHOO.util.DragDrop.html">YAHOO.util.DragDrop</a> object we are working with.
|
|
463 * @description Resizes the proxy, sets up the <a href="YAHOO.util.DragDrop.html">YAHOO.util.DragDrop</a> handlers, updates the status div and preps the cache
|
|
464 */
|
|
465 _handleStartDrag: function(args, dd) {
|
|
466 var tar = dd.getDragEl();
|
|
467 if (D.hasClass(tar, this.CSS_HANDLE)) {
|
|
468 if (D.getStyle(this._wrap, 'position') == 'absolute') {
|
|
469 this._positioned = true;
|
|
470 }
|
|
471 this._active = true;
|
|
472 this._currentDD = dd;
|
|
473 if (this._proxy) {
|
|
474 this._proxy.style.visibility = 'visible';
|
|
475 this._proxy.style.zIndex = '1000';
|
|
476 this._proxy.style.height = this.get('element').clientHeight + 'px';
|
|
477 this._proxy.style.width = this.get('element').clientWidth + 'px';
|
|
478 }
|
|
479
|
|
480 for (var i in this._handles) {
|
|
481 if (Lang.hasOwnProperty(this._handles, i)) {
|
|
482 if (this._handles[i] == tar) {
|
|
483 this._currentHandle = i;
|
|
484 var handle = '_handle_for_' + i;
|
|
485 D.addClass(tar, this.CSS_HANDLE + '-' + i + '-active');
|
|
486 dd.on('dragEvent', this[handle], this, true);
|
|
487 dd.on('mouseUpEvent', this._handleMouseUp, this, true);
|
|
488 break;
|
|
489 }
|
|
490 }
|
|
491 }
|
|
492
|
|
493
|
|
494 D.addClass(tar, this.CSS_HANDLE + '-active');
|
|
495
|
|
496 if (this.get('proxy')) {
|
|
497 var xy = D.getXY(this.get('element'));
|
|
498 D.setXY(this._proxy, xy);
|
|
499 if (this.get('ghost')) {
|
|
500 this.addClass(this.CSS_GHOST);
|
|
501 }
|
|
502 }
|
|
503 D.addClass(this._wrap, this.CSS_RESIZING);
|
|
504 this._setCache();
|
|
505 this._updateStatus(this._cache.height, this._cache.width, this._cache.top, this._cache.left);
|
|
506 this.fireEvent('startResize', { type: 'startresize', target: this});
|
|
507 }
|
|
508 },
|
|
509 /**
|
|
510 * @private
|
|
511 * @method _setCache
|
|
512 * @description Sets up the this._cache hash table.
|
|
513 */
|
|
514 _setCache: function() {
|
|
515 this._cache.xy = D.getXY(this._wrap);
|
|
516 D.setXY(this._wrap, this._cache.xy);
|
|
517 this._cache.height = this.get('clientHeight');
|
|
518 this._cache.width = this.get('clientWidth');
|
|
519 this._cache.start.height = this._cache.height;
|
|
520 this._cache.start.width = this._cache.width;
|
|
521 this._cache.start.top = this._cache.xy[1];
|
|
522 this._cache.start.left = this._cache.xy[0];
|
|
523 this._cache.top = this._cache.xy[1];
|
|
524 this._cache.left = this._cache.xy[0];
|
|
525 this.set('height', this._cache.height, true);
|
|
526 this.set('width', this._cache.width, true);
|
|
527 },
|
|
528 /**
|
|
529 * @private
|
|
530 * @method _handleMouseUp
|
|
531 * @param {Event} ev A mouse event.
|
|
532 * @description Cleans up listeners, hides proxy element and removes class names.
|
|
533 */
|
|
534 _handleMouseUp: function(ev) {
|
|
535 this._active = false;
|
|
536
|
|
537 var handle = '_handle_for_' + this._currentHandle;
|
|
538 this._currentDD.unsubscribe('dragEvent', this[handle], this, true);
|
|
539 this._currentDD.unsubscribe('mouseUpEvent', this._handleMouseUp, this, true);
|
|
540
|
|
541 if (this._proxy) {
|
|
542 this._proxy.style.visibility = 'hidden';
|
|
543 this._proxy.style.zIndex = '-1';
|
|
544 if (this.get('setSize')) {
|
|
545 this.resize(ev, this._cache.height, this._cache.width, this._cache.top, this._cache.left, true);
|
|
546 } else {
|
|
547 this.fireEvent('resize', { ev: 'resize', target: this, height: this._cache.height, width: this._cache.width, top: this._cache.top, left: this._cache.left });
|
|
548 }
|
|
549
|
|
550 if (this.get('ghost')) {
|
|
551 this.removeClass(this.CSS_GHOST);
|
|
552 }
|
|
553 }
|
|
554
|
|
555 if (this.get('hover')) {
|
|
556 D.addClass(this._wrap, this.CSS_HOVER);
|
|
557 }
|
|
558 if (this._status) {
|
|
559 D.setStyle(this._status, 'display', 'none');
|
|
560 }
|
|
561 if (this.browser.ie) {
|
|
562 document.body.onselectstart = this._ieSelectBack;
|
|
563 }
|
|
564
|
|
565 if (this.browser.ie) {
|
|
566 D.removeClass(this._wrap, this.CSS_RESIZE);
|
|
567 }
|
|
568
|
|
569 for (var i in this._handles) {
|
|
570 if (Lang.hasOwnProperty(this._handles, i)) {
|
|
571 D.removeClass(this._handles[i], this.CSS_HANDLE + '-active');
|
|
572 }
|
|
573 }
|
|
574 if (this.get('hover') && !this._active) {
|
|
575 D.addClass(this._wrap, this.CSS_HOVER);
|
|
576 }
|
|
577 D.removeClass(this._wrap, this.CSS_RESIZING);
|
|
578
|
|
579 D.removeClass(this._handles[this._currentHandle], this.CSS_HANDLE + '-' + this._currentHandle + '-active');
|
|
580 D.removeClass(this._handles[this._currentHandle], this.CSS_HANDLE + '-active');
|
|
581
|
|
582 if (this.browser.ie) {
|
|
583 D.addClass(this._wrap, this.CSS_RESIZE);
|
|
584 }
|
|
585
|
|
586 this._resizeEvent = null;
|
|
587 this._currentHandle = null;
|
|
588
|
|
589 if (!this.get('animate')) {
|
|
590 this.set('height', this._cache.height, true);
|
|
591 this.set('width', this._cache.width, true);
|
|
592 }
|
|
593
|
|
594 this.fireEvent('endResize', { ev: 'endResize', target: this, height: this._cache.height, width: this._cache.width, top: this._cache.top, left: this._cache.left });
|
|
595 },
|
|
596 /**
|
|
597 * @private
|
|
598 * @method _setRatio
|
|
599 * @param {Number} h The height offset.
|
|
600 * @param {Number} w The with offset.
|
|
601 * @param {Number} t The top offset.
|
|
602 * @param {Number} l The left offset.
|
|
603 * @description Using the Height, Width, Top & Left, it recalcuates them based on the original element size.
|
|
604 * @return {Array} The new Height, Width, Top & Left settings
|
|
605 */
|
|
606 _setRatio: function(h, w, t, l) {
|
|
607 var oh = h, ow = w;
|
|
608 if (this.get('ratio')) {
|
|
609 var orgH = this._cache.height,
|
|
610 orgW = this._cache.width,
|
|
611 nh = parseInt(this.get('height'), 10),
|
|
612 nw = parseInt(this.get('width'), 10),
|
|
613 maxH = this.get('maxHeight'),
|
|
614 minH = this.get('minHeight'),
|
|
615 maxW = this.get('maxWidth'),
|
|
616 minW = this.get('minWidth');
|
|
617
|
|
618 switch (this._currentHandle) {
|
|
619 case 'l':
|
|
620 h = nh * (w / nw);
|
|
621 h = Math.min(Math.max(minH, h), maxH);
|
|
622 w = nw * (h / nh);
|
|
623 t = (this._cache.start.top - (-((nh - h) / 2)));
|
|
624 l = (this._cache.start.left - (-((nw - w))));
|
|
625 break;
|
|
626 case 'r':
|
|
627 h = nh * (w / nw);
|
|
628 h = Math.min(Math.max(minH, h), maxH);
|
|
629 w = nw * (h / nh);
|
|
630 t = (this._cache.start.top - (-((nh - h) / 2)));
|
|
631 break;
|
|
632 case 't':
|
|
633 w = nw * (h / nh);
|
|
634 h = nh * (w / nw);
|
|
635 l = (this._cache.start.left - (-((nw - w) / 2)));
|
|
636 t = (this._cache.start.top - (-((nh - h))));
|
|
637 break;
|
|
638 case 'b':
|
|
639 w = nw * (h / nh);
|
|
640 h = nh * (w / nw);
|
|
641 l = (this._cache.start.left - (-((nw - w) / 2)));
|
|
642 break;
|
|
643 case 'bl':
|
|
644 h = nh * (w / nw);
|
|
645 w = nw * (h / nh);
|
|
646 l = (this._cache.start.left - (-((nw - w))));
|
|
647 break;
|
|
648 case 'br':
|
|
649 h = nh * (w / nw);
|
|
650 w = nw * (h / nh);
|
|
651 break;
|
|
652 case 'tl':
|
|
653 h = nh * (w / nw);
|
|
654 w = nw * (h / nh);
|
|
655 l = (this._cache.start.left - (-((nw - w))));
|
|
656 t = (this._cache.start.top - (-((nh - h))));
|
|
657 break;
|
|
658 case 'tr':
|
|
659 h = nh * (w / nw);
|
|
660 w = nw * (h / nh);
|
|
661 l = (this._cache.start.left);
|
|
662 t = (this._cache.start.top - (-((nh - h))));
|
|
663 break;
|
|
664 }
|
|
665 oh = this._checkHeight(h);
|
|
666 ow = this._checkWidth(w);
|
|
667 if ((oh != h) || (ow != w)) {
|
|
668 t = 0;
|
|
669 l = 0;
|
|
670 if (oh != h) {
|
|
671 ow = this._cache.width;
|
|
672 }
|
|
673 if (ow != w) {
|
|
674 oh = this._cache.height;
|
|
675 }
|
|
676 }
|
|
677 }
|
|
678 return [oh, ow, t, l];
|
|
679 },
|
|
680 /**
|
|
681 * @private
|
|
682 * @method _updateStatus
|
|
683 * @param {Number} h The new height setting.
|
|
684 * @param {Number} w The new width setting.
|
|
685 * @param {Number} t The new top setting.
|
|
686 * @param {Number} l The new left setting.
|
|
687 * @description Using the Height, Width, Top & Left, it updates the status element with the elements sizes.
|
|
688 */
|
|
689 _updateStatus: function(h, w, t, l) {
|
|
690 if (this._resizeEvent && (!Lang.isString(this._resizeEvent))) {
|
|
691 h = ((h === 0) ? this._cache.start.height : h);
|
|
692 w = ((w === 0) ? this._cache.start.width : w);
|
|
693 var h1 = parseInt(this.get('height'), 10),
|
|
694 w1 = parseInt(this.get('width'), 10);
|
|
695
|
|
696 if (isNaN(h1)) {
|
|
697 h1 = parseInt(h, 10);
|
|
698 }
|
|
699 if (isNaN(w1)) {
|
|
700 w1 = parseInt(w, 10);
|
|
701 }
|
|
702 var diffH = (parseInt(h, 10) - h1);
|
|
703 var diffW = (parseInt(w, 10) - w1);
|
|
704 this._cache.offsetHeight = diffH;
|
|
705 this._cache.offsetWidth = diffW;
|
|
706 if (this.get('status')) {
|
|
707 D.setStyle(this._status, 'display', 'inline');
|
|
708 //This will cause IE8 to crash if the status box is hidden..
|
|
709 this._status.innerHTML = '<strong>' + parseInt(h, 10) + ' x ' + parseInt(w, 10) + '</strong><em>' + ((diffH > 0) ? '+' : '') + diffH + ' x ' + ((diffW > 0) ? '+' : '') + diffW + '</em>';
|
|
710 D.setXY(this._status, [Event.getPageX(this._resizeEvent) + 12, Event.getPageY(this._resizeEvent) + 12]);
|
|
711 }
|
|
712 }
|
|
713 },
|
|
714 /**
|
|
715 * @method lock
|
|
716 * @description Lock the resize so it can't be resized
|
|
717 * @param {Boolean} dd If the draggable config is set, lock it too
|
|
718 * @return {<a href="YAHOO.util.Resize.html">YAHOO.util.Resize</a>} The Resize instance
|
|
719 */
|
|
720 lock: function(dd) {
|
|
721 this._locked = true;
|
|
722 if (dd && this.dd) {
|
|
723 D.removeClass(this._wrap, 'yui-draggable');
|
|
724 this.dd.lock();
|
|
725 }
|
|
726 return this;
|
|
727 },
|
|
728 /**
|
|
729 * @method unlock
|
|
730 * @description Unlock the resize so it can be resized
|
|
731 * @param {Boolean} dd If the draggable config is set, unlock it too
|
|
732 * @return {<a href="YAHOO.util.Resize.html">YAHOO.util.Resize</a>} The Resize instance
|
|
733 */
|
|
734 unlock: function(dd) {
|
|
735 this._locked = false;
|
|
736 if (dd && this.dd) {
|
|
737 D.addClass(this._wrap, 'yui-draggable');
|
|
738 this.dd.unlock();
|
|
739 }
|
|
740 return this;
|
|
741 },
|
|
742 /**
|
|
743 * @method isLocked
|
|
744 * @description Check the locked status of the resize instance
|
|
745 * @return {Boolean}
|
|
746 */
|
|
747 isLocked: function() {
|
|
748 return this._locked;
|
|
749 },
|
|
750 /**
|
|
751 * @method reset
|
|
752 * @description Resets the element to is start state.
|
|
753 * @return {<a href="YAHOO.util.Resize.html">YAHOO.util.Resize</a>} The Resize instance
|
|
754 */
|
|
755 reset: function() {
|
|
756 this.resize(null, this._cache.start.height, this._cache.start.width, this._cache.start.top, this._cache.start.left, true);
|
|
757 return this;
|
|
758 },
|
|
759 /**
|
|
760 * @private
|
|
761 * @method resize
|
|
762 * @param {Event} ev The mouse event.
|
|
763 * @param {Number} h The new height setting.
|
|
764 * @param {Number} w The new width setting.
|
|
765 * @param {Number} t The new top setting.
|
|
766 * @param {Number} l The new left setting.
|
|
767 * @param {Boolean} force Resize the element (used for proxy resize).
|
|
768 * @param {Boolean} silent Don't fire the beforeResize Event.
|
|
769 * @description Resizes the element, wrapper or proxy based on the data from the handlers.
|
|
770 * @return {<a href="YAHOO.util.Resize.html">YAHOO.util.Resize</a>} The Resize instance
|
|
771 */
|
|
772 resize: function(ev, h, w, t, l, force, silent) {
|
|
773 if (this._locked) {
|
|
774 return false;
|
|
775 }
|
|
776 this._resizeEvent = ev;
|
|
777 var el = this._wrap, anim = this.get('animate'), set = true;
|
|
778 if (this._proxy && !force) {
|
|
779 el = this._proxy;
|
|
780 anim = false;
|
|
781 }
|
|
782 this._setAutoRatio(ev);
|
|
783 if (this._positioned) {
|
|
784 if (this._proxy) {
|
|
785 t = this._cache.top - t;
|
|
786 l = this._cache.left - l;
|
|
787 }
|
|
788 }
|
|
789
|
|
790
|
|
791 var ratio = this._setRatio(h, w, t, l);
|
|
792 h = parseInt(ratio[0], 10);
|
|
793 w = parseInt(ratio[1], 10);
|
|
794 t = parseInt(ratio[2], 10);
|
|
795 l = parseInt(ratio[3], 10);
|
|
796
|
|
797 if (t == 0) {
|
|
798 //No Offset, get from cache
|
|
799 t = D.getY(el);
|
|
800 }
|
|
801 if (l == 0) {
|
|
802 //No Offset, get from cache
|
|
803 l = D.getX(el);
|
|
804 }
|
|
805
|
|
806
|
|
807
|
|
808 if (this._positioned) {
|
|
809 if (this._proxy && force) {
|
|
810 if (!anim) {
|
|
811 el.style.top = this._proxy.style.top;
|
|
812 el.style.left = this._proxy.style.left;
|
|
813 } else {
|
|
814 t = this._proxy.style.top;
|
|
815 l = this._proxy.style.left;
|
|
816 }
|
|
817 } else {
|
|
818 if (!this.get('ratio') && !this._proxy) {
|
|
819 t = this._cache.top + -(t);
|
|
820 l = this._cache.left + -(l);
|
|
821 }
|
|
822 if (t) {
|
|
823 if (this.get('minY')) {
|
|
824 if (t < this.get('minY')) {
|
|
825 t = this.get('minY');
|
|
826 }
|
|
827 }
|
|
828 if (this.get('maxY')) {
|
|
829 if (t > this.get('maxY')) {
|
|
830 t = this.get('maxY');
|
|
831 }
|
|
832 }
|
|
833 }
|
|
834 if (l) {
|
|
835 if (this.get('minX')) {
|
|
836 if (l < this.get('minX')) {
|
|
837 l = this.get('minX');
|
|
838 }
|
|
839 }
|
|
840 if (this.get('maxX')) {
|
|
841 if ((l + w) > this.get('maxX')) {
|
|
842 l = (this.get('maxX') - w);
|
|
843 }
|
|
844 }
|
|
845 }
|
|
846 }
|
|
847 }
|
|
848 if (!silent) {
|
|
849 var beforeReturn = this.fireEvent('beforeResize', { ev: 'beforeResize', target: this, height: h, width: w, top: t, left: l });
|
|
850 if (beforeReturn === false) {
|
|
851 return false;
|
|
852 }
|
|
853 }
|
|
854
|
|
855 this._updateStatus(h, w, t, l);
|
|
856
|
|
857
|
|
858 if (this._positioned) {
|
|
859 if (this._proxy && force) {
|
|
860 //Do nothing
|
|
861 } else {
|
|
862 if (t) {
|
|
863 D.setY(el, t);
|
|
864 this._cache.top = t;
|
|
865 }
|
|
866 if (l) {
|
|
867 D.setX(el, l);
|
|
868 this._cache.left = l;
|
|
869 }
|
|
870 }
|
|
871 }
|
|
872 if (h) {
|
|
873 if (!anim) {
|
|
874 set = true;
|
|
875 if (this._proxy && force) {
|
|
876 if (!this.get('setSize')) {
|
|
877 set = false;
|
|
878 }
|
|
879 }
|
|
880 if (set) {
|
|
881 el.style.height = h + 'px';
|
|
882 }
|
|
883 if ((this._proxy && force) || !this._proxy) {
|
|
884 if (this._wrap != this.get('element')) {
|
|
885 this.get('element').style.height = h + 'px';
|
|
886 }
|
|
887 }
|
|
888 }
|
|
889 this._cache.height = h;
|
|
890 }
|
|
891 if (w) {
|
|
892 this._cache.width = w;
|
|
893 if (!anim) {
|
|
894 set = true;
|
|
895 if (this._proxy && force) {
|
|
896 if (!this.get('setSize')) {
|
|
897 set = false;
|
|
898 }
|
|
899 }
|
|
900 if (set) {
|
|
901 el.style.width = w + 'px';
|
|
902 }
|
|
903 if ((this._proxy && force) || !this._proxy) {
|
|
904 if (this._wrap != this.get('element')) {
|
|
905 this.get('element').style.width = w + 'px';
|
|
906 }
|
|
907 }
|
|
908 }
|
|
909 }
|
|
910 if (anim) {
|
|
911 if (YAHOO.util.Anim) {
|
|
912 var _anim = new YAHOO.util.Anim(el, {
|
|
913 height: {
|
|
914 to: this._cache.height
|
|
915 },
|
|
916 width: {
|
|
917 to: this._cache.width
|
|
918 }
|
|
919 }, this.get('animateDuration'), this.get('animateEasing'));
|
|
920 if (this._positioned) {
|
|
921 if (t) {
|
|
922 _anim.attributes.top = {
|
|
923 to: parseInt(t, 10)
|
|
924 };
|
|
925 }
|
|
926 if (l) {
|
|
927 _anim.attributes.left = {
|
|
928 to: parseInt(l, 10)
|
|
929 };
|
|
930 }
|
|
931 }
|
|
932
|
|
933 if (this._wrap != this.get('element')) {
|
|
934 _anim.onTween.subscribe(function() {
|
|
935 this.get('element').style.height = el.style.height;
|
|
936 this.get('element').style.width = el.style.width;
|
|
937 }, this, true);
|
|
938 }
|
|
939
|
|
940 _anim.onComplete.subscribe(function() {
|
|
941 this.set('height', h);
|
|
942 this.set('width', w);
|
|
943 this.fireEvent('resize', { ev: 'resize', target: this, height: h, width: w, top: t, left: l });
|
|
944 }, this, true);
|
|
945 _anim.animate();
|
|
946
|
|
947 }
|
|
948 } else {
|
|
949 if (this._proxy && !force) {
|
|
950 this.fireEvent('proxyResize', { ev: 'proxyresize', target: this, height: h, width: w, top: t, left: l });
|
|
951 } else {
|
|
952 this.fireEvent('resize', { ev: 'resize', target: this, height: h, width: w, top: t, left: l });
|
|
953 }
|
|
954 }
|
|
955 return this;
|
|
956 },
|
|
957 /**
|
|
958 * @private
|
|
959 * @method _handle_for_br
|
|
960 * @param {Object} args The arguments from the CustomEvent.
|
|
961 * @description Handles the sizes for the Bottom Right handle.
|
|
962 */
|
|
963 _handle_for_br: function(args) {
|
|
964 var newW = this._setWidth(args.e);
|
|
965 var newH = this._setHeight(args.e);
|
|
966 this.resize(args.e, newH, newW, 0, 0);
|
|
967 },
|
|
968 /**
|
|
969 * @private
|
|
970 * @method _handle_for_bl
|
|
971 * @param {Object} args The arguments from the CustomEvent.
|
|
972 * @description Handles the sizes for the Bottom Left handle.
|
|
973 */
|
|
974 _handle_for_bl: function(args) {
|
|
975 var newW = this._setWidth(args.e, true);
|
|
976 var newH = this._setHeight(args.e);
|
|
977 var l = (newW - this._cache.width);
|
|
978 this.resize(args.e, newH, newW, 0, l);
|
|
979 },
|
|
980 /**
|
|
981 * @private
|
|
982 * @method _handle_for_tl
|
|
983 * @param {Object} args The arguments from the CustomEvent.
|
|
984 * @description Handles the sizes for the Top Left handle.
|
|
985 */
|
|
986 _handle_for_tl: function(args) {
|
|
987 var newW = this._setWidth(args.e, true);
|
|
988 var newH = this._setHeight(args.e, true);
|
|
989 var t = (newH - this._cache.height);
|
|
990 var l = (newW - this._cache.width);
|
|
991 this.resize(args.e, newH, newW, t, l);
|
|
992 },
|
|
993 /**
|
|
994 * @private
|
|
995 * @method _handle_for_tr
|
|
996 * @param {Object} args The arguments from the CustomEvent.
|
|
997 * @description Handles the sizes for the Top Right handle.
|
|
998 */
|
|
999 _handle_for_tr: function(args) {
|
|
1000 var newW = this._setWidth(args.e);
|
|
1001 var newH = this._setHeight(args.e, true);
|
|
1002 var t = (newH - this._cache.height);
|
|
1003 this.resize(args.e, newH, newW, t, 0);
|
|
1004 },
|
|
1005 /**
|
|
1006 * @private
|
|
1007 * @method _handle_for_r
|
|
1008 * @param {Object} args The arguments from the CustomEvent.
|
|
1009 * @description Handles the sizes for the Right handle.
|
|
1010 */
|
|
1011 _handle_for_r: function(args) {
|
|
1012 this._dds.r.setYConstraint(0,0);
|
|
1013 var newW = this._setWidth(args.e);
|
|
1014 this.resize(args.e, 0, newW, 0, 0);
|
|
1015 },
|
|
1016 /**
|
|
1017 * @private
|
|
1018 * @method _handle_for_l
|
|
1019 * @param {Object} args The arguments from the CustomEvent.
|
|
1020 * @description Handles the sizes for the Left handle.
|
|
1021 */
|
|
1022 _handle_for_l: function(args) {
|
|
1023 this._dds.l.setYConstraint(0,0);
|
|
1024 var newW = this._setWidth(args.e, true);
|
|
1025 var l = (newW - this._cache.width);
|
|
1026 this.resize(args.e, 0, newW, 0, l);
|
|
1027 },
|
|
1028 /**
|
|
1029 * @private
|
|
1030 * @method _handle_for_b
|
|
1031 * @param {Object} args The arguments from the CustomEvent.
|
|
1032 * @description Handles the sizes for the Bottom handle.
|
|
1033 */
|
|
1034 _handle_for_b: function(args) {
|
|
1035 this._dds.b.setXConstraint(0,0);
|
|
1036 var newH = this._setHeight(args.e);
|
|
1037 this.resize(args.e, newH, 0, 0, 0);
|
|
1038 },
|
|
1039 /**
|
|
1040 * @private
|
|
1041 * @method _handle_for_t
|
|
1042 * @param {Object} args The arguments from the CustomEvent.
|
|
1043 * @description Handles the sizes for the Top handle.
|
|
1044 */
|
|
1045 _handle_for_t: function(args) {
|
|
1046 this._dds.t.setXConstraint(0,0);
|
|
1047 var newH = this._setHeight(args.e, true);
|
|
1048 var t = (newH - this._cache.height);
|
|
1049 this.resize(args.e, newH, 0, t, 0);
|
|
1050 },
|
|
1051 /**
|
|
1052 * @private
|
|
1053 * @method _setWidth
|
|
1054 * @param {Event} ev The mouse event.
|
|
1055 * @param {Boolean} flip Argument to determine the direction of the movement.
|
|
1056 * @description Calculates the width based on the mouse event.
|
|
1057 * @return {Number} The new value
|
|
1058 */
|
|
1059 _setWidth: function(ev, flip) {
|
|
1060 var xy = this._cache.xy[0],
|
|
1061 w = this._cache.width,
|
|
1062 x = Event.getPageX(ev),
|
|
1063 nw = (x - xy);
|
|
1064
|
|
1065 if (flip) {
|
|
1066 nw = (xy - x) + parseInt(this.get('width'), 10);
|
|
1067 }
|
|
1068
|
|
1069 nw = this._snapTick(nw, this.get('xTicks'));
|
|
1070 nw = this._checkWidth(nw);
|
|
1071 return nw;
|
|
1072 },
|
|
1073 /**
|
|
1074 * @private
|
|
1075 * @method _checkWidth
|
|
1076 * @param {Number} w The width to check.
|
|
1077 * @description Checks the value passed against the maxWidth and minWidth.
|
|
1078 * @return {Number} the new value
|
|
1079 */
|
|
1080 _checkWidth: function(w) {
|
|
1081 if (this.get('minWidth')) {
|
|
1082 if (w <= this.get('minWidth')) {
|
|
1083 w = this.get('minWidth');
|
|
1084 }
|
|
1085 }
|
|
1086 if (this.get('maxWidth')) {
|
|
1087 if (w >= this.get('maxWidth')) {
|
|
1088 w = this.get('maxWidth');
|
|
1089 }
|
|
1090 }
|
|
1091 return w;
|
|
1092 },
|
|
1093 /**
|
|
1094 * @private
|
|
1095 * @method _checkHeight
|
|
1096 * @param {Number} h The height to check.
|
|
1097 * @description Checks the value passed against the maxHeight and minHeight.
|
|
1098 * @return {Number} The new value
|
|
1099 */
|
|
1100 _checkHeight: function(h) {
|
|
1101 if (this.get('minHeight')) {
|
|
1102 if (h <= this.get('minHeight')) {
|
|
1103 h = this.get('minHeight');
|
|
1104 }
|
|
1105 }
|
|
1106 if (this.get('maxHeight')) {
|
|
1107 if (h >= this.get('maxHeight')) {
|
|
1108 h = this.get('maxHeight');
|
|
1109 }
|
|
1110 }
|
|
1111 return h;
|
|
1112 },
|
|
1113 /**
|
|
1114 * @private
|
|
1115 * @method _setHeight
|
|
1116 * @param {Event} ev The mouse event.
|
|
1117 * @param {Boolean} flip Argument to determine the direction of the movement.
|
|
1118 * @description Calculated the height based on the mouse event.
|
|
1119 * @return {Number} The new value
|
|
1120 */
|
|
1121 _setHeight: function(ev, flip) {
|
|
1122 var xy = this._cache.xy[1],
|
|
1123 h = this._cache.height,
|
|
1124 y = Event.getPageY(ev),
|
|
1125 nh = (y - xy);
|
|
1126
|
|
1127 if (flip) {
|
|
1128 nh = (xy - y) + parseInt(this.get('height'), 10);
|
|
1129 }
|
|
1130 nh = this._snapTick(nh, this.get('yTicks'));
|
|
1131 nh = this._checkHeight(nh);
|
|
1132
|
|
1133 return nh;
|
|
1134 },
|
|
1135 /**
|
|
1136 * @private
|
|
1137 * @method _snapTick
|
|
1138 * @param {Number} size The size to tick against.
|
|
1139 * @param {Number} pix The tick pixels.
|
|
1140 * @description Adjusts the number based on the ticks used.
|
|
1141 * @return {Number} the new snapped position
|
|
1142 */
|
|
1143 _snapTick: function(size, pix) {
|
|
1144 if (!size || !pix) {
|
|
1145 return size;
|
|
1146 }
|
|
1147 var _s = size;
|
|
1148 var _x = size % pix;
|
|
1149 if (_x > 0) {
|
|
1150 if (_x > (pix / 2)) {
|
|
1151 _s = size + (pix - _x);
|
|
1152 } else {
|
|
1153 _s = size - _x;
|
|
1154 }
|
|
1155 }
|
|
1156 return _s;
|
|
1157 },
|
|
1158 /**
|
|
1159 * @private
|
|
1160 * @method init
|
|
1161 * @description The Resize class's initialization method
|
|
1162 */
|
|
1163 init: function(p_oElement, p_oAttributes) {
|
|
1164 this._locked = false;
|
|
1165 this._cache = {
|
|
1166 xy: [],
|
|
1167 height: 0,
|
|
1168 width: 0,
|
|
1169 top: 0,
|
|
1170 left: 0,
|
|
1171 offsetHeight: 0,
|
|
1172 offsetWidth: 0,
|
|
1173 start: {
|
|
1174 height: 0,
|
|
1175 width: 0,
|
|
1176 top: 0,
|
|
1177 left: 0
|
|
1178 }
|
|
1179 };
|
|
1180
|
|
1181 Resize.superclass.init.call(this, p_oElement, p_oAttributes);
|
|
1182
|
|
1183 this.set('setSize', this.get('setSize'));
|
|
1184
|
|
1185 if (p_oAttributes.height) {
|
|
1186 this.set('height', parseInt(p_oAttributes.height, 10));
|
|
1187 } else {
|
|
1188 var h = this.getStyle('height');
|
|
1189 if (h == 'auto') {
|
|
1190 this.set('height', parseInt(this.get('element').offsetHeight, 10));
|
|
1191 }
|
|
1192 }
|
|
1193 if (p_oAttributes.width) {
|
|
1194 this.set('width', parseInt(p_oAttributes.width, 10));
|
|
1195 } else {
|
|
1196 var w = this.getStyle('width');
|
|
1197 if (w == 'auto') {
|
|
1198 this.set('width', parseInt(this.get('element').offsetWidth, 10));
|
|
1199 }
|
|
1200 }
|
|
1201
|
|
1202 var id = p_oElement;
|
|
1203 if (!Lang.isString(id)) {
|
|
1204 id = D.generateId(id);
|
|
1205 }
|
|
1206 Resize._instances[id] = this;
|
|
1207
|
|
1208 this._active = false;
|
|
1209
|
|
1210 this._createWrap();
|
|
1211 this._createProxy();
|
|
1212 this._createHandles();
|
|
1213
|
|
1214 },
|
|
1215 /**
|
|
1216 * @method getProxyEl
|
|
1217 * @description Get the HTML reference for the proxy, returns null if no proxy.
|
|
1218 * @return {HTMLElement} The proxy element
|
|
1219 */
|
|
1220 getProxyEl: function() {
|
|
1221 return this._proxy;
|
|
1222 },
|
|
1223 /**
|
|
1224 * @method getWrapEl
|
|
1225 * @description Get the HTML reference for the wrap element, returns the current element if not wrapped.
|
|
1226 * @return {HTMLElement} The wrap element
|
|
1227 */
|
|
1228 getWrapEl: function() {
|
|
1229 return this._wrap;
|
|
1230 },
|
|
1231 /**
|
|
1232 * @method getStatusEl
|
|
1233 * @description Get the HTML reference for the status element.
|
|
1234 * @return {HTMLElement} The status element
|
|
1235 */
|
|
1236 getStatusEl: function() {
|
|
1237 return this._status;
|
|
1238 },
|
|
1239 /**
|
|
1240 * @method getActiveHandleEl
|
|
1241 * @description Get the HTML reference for the currently active resize handle.
|
|
1242 * @return {HTMLElement} The handle element that is active
|
|
1243 */
|
|
1244 getActiveHandleEl: function() {
|
|
1245 return this._handles[this._currentHandle];
|
|
1246 },
|
|
1247 /**
|
|
1248 * @method isActive
|
|
1249 * @description Returns true or false if a resize operation is currently active on the element.
|
|
1250 * @return {Boolean}
|
|
1251 */
|
|
1252 isActive: function() {
|
|
1253 return ((this._active) ? true : false);
|
|
1254 },
|
|
1255 /**
|
|
1256 * @private
|
|
1257 * @method initAttributes
|
|
1258 * @description Initializes all of the configuration attributes used to create a resizable element.
|
|
1259 * @param {Object} attr Object literal specifying a set of
|
|
1260 * configuration attributes used to create the utility.
|
|
1261 */
|
|
1262 initAttributes: function(attr) {
|
|
1263 Resize.superclass.initAttributes.call(this, attr);
|
|
1264
|
|
1265 /**
|
|
1266 * @attribute useShim
|
|
1267 * @description This setting will be passed to the DragDrop instances on the resize handles and for the draggable property.
|
|
1268 * This property should be used if you want the resize handles to work over iframe and other elements.
|
|
1269 * @type Boolean
|
|
1270 */
|
|
1271 this.setAttributeConfig('useShim', {
|
|
1272 value: ((attr.useShim === true) ? true : false),
|
|
1273 validator: YAHOO.lang.isBoolean,
|
|
1274 method: function(u) {
|
|
1275 for (var i in this._dds) {
|
|
1276 if (Lang.hasOwnProperty(this._dds, i)) {
|
|
1277 this._dds[i].useShim = u;
|
|
1278 }
|
|
1279 }
|
|
1280 if (this.dd) {
|
|
1281 this.dd.useShim = u;
|
|
1282 }
|
|
1283 }
|
|
1284 });
|
|
1285 /**
|
|
1286 * @attribute setSize
|
|
1287 * @description Set the size of the resized element, if set to false the element will not be auto resized,
|
|
1288 * the resize event will contain the dimensions so the end user can resize it on their own.
|
|
1289 * This setting will only work with proxy set to true and animate set to false.
|
|
1290 * @type Boolean
|
|
1291 */
|
|
1292 this.setAttributeConfig('setSize', {
|
|
1293 value: ((attr.setSize === false) ? false : true),
|
|
1294 validator: YAHOO.lang.isBoolean
|
|
1295 });
|
|
1296
|
|
1297 /**
|
|
1298 * @attribute wrap
|
|
1299 * @description Should we wrap the element
|
|
1300 * @type Boolean
|
|
1301 */
|
|
1302 this.setAttributeConfig('wrap', {
|
|
1303 writeOnce: true,
|
|
1304 validator: YAHOO.lang.isBoolean,
|
|
1305 value: attr.wrap || false
|
|
1306 });
|
|
1307
|
|
1308 /**
|
|
1309 * @attribute handles
|
|
1310 * @description The handles to use (any combination of): 't', 'b', 'r', 'l', 'bl', 'br', 'tl', 'tr'. Defaults to: ['r', 'b', 'br'].
|
|
1311 * Can use a shortcut of All. Note: 8 way resizing should be done on an element that is absolutely positioned.
|
|
1312 * @type Array
|
|
1313 */
|
|
1314 this.setAttributeConfig('handles', {
|
|
1315 writeOnce: true,
|
|
1316 value: attr.handles || ['r', 'b', 'br'],
|
|
1317 validator: function(handles) {
|
|
1318 if (Lang.isString(handles) && handles.toLowerCase() == 'all') {
|
|
1319 handles = ['t', 'b', 'r', 'l', 'bl', 'br', 'tl', 'tr'];
|
|
1320 }
|
|
1321 if (!Lang.isArray(handles)) {
|
|
1322 handles = handles.replace(/, /g, ',');
|
|
1323 handles = handles.split(',');
|
|
1324 }
|
|
1325 this._configs.handles.value = handles;
|
|
1326 }
|
|
1327 });
|
|
1328
|
|
1329 /**
|
|
1330 * @attribute width
|
|
1331 * @description The width of the element
|
|
1332 * @type Number
|
|
1333 */
|
|
1334 this.setAttributeConfig('width', {
|
|
1335 value: attr.width || parseInt(this.getStyle('width'), 10),
|
|
1336 validator: YAHOO.lang.isNumber,
|
|
1337 method: function(width) {
|
|
1338 width = parseInt(width, 10);
|
|
1339 if (width > 0) {
|
|
1340 if (this.get('setSize')) {
|
|
1341 this.setStyle('width', width + 'px');
|
|
1342 }
|
|
1343 this._cache.width = width;
|
|
1344 this._configs.width.value = width;
|
|
1345 }
|
|
1346 }
|
|
1347 });
|
|
1348
|
|
1349 /**
|
|
1350 * @attribute height
|
|
1351 * @description The height of the element
|
|
1352 * @type Number
|
|
1353 */
|
|
1354 this.setAttributeConfig('height', {
|
|
1355 value: attr.height || parseInt(this.getStyle('height'), 10),
|
|
1356 validator: YAHOO.lang.isNumber,
|
|
1357 method: function(height) {
|
|
1358 height = parseInt(height, 10);
|
|
1359 if (height > 0) {
|
|
1360 if (this.get('setSize')) {
|
|
1361 this.setStyle('height', height + 'px');
|
|
1362 }
|
|
1363 this._cache.height = height;
|
|
1364 this._configs.height.value = height;
|
|
1365 }
|
|
1366 }
|
|
1367 });
|
|
1368
|
|
1369 /**
|
|
1370 * @attribute minWidth
|
|
1371 * @description The minimum width of the element
|
|
1372 * @type Number
|
|
1373 */
|
|
1374 this.setAttributeConfig('minWidth', {
|
|
1375 value: attr.minWidth || 15,
|
|
1376 validator: YAHOO.lang.isNumber
|
|
1377 });
|
|
1378
|
|
1379 /**
|
|
1380 * @attribute minHeight
|
|
1381 * @description The minimum height of the element
|
|
1382 * @type Number
|
|
1383 */
|
|
1384 this.setAttributeConfig('minHeight', {
|
|
1385 value: attr.minHeight || 15,
|
|
1386 validator: YAHOO.lang.isNumber
|
|
1387 });
|
|
1388
|
|
1389 /**
|
|
1390 * @attribute maxWidth
|
|
1391 * @description The maximum width of the element
|
|
1392 * @type Number
|
|
1393 */
|
|
1394 this.setAttributeConfig('maxWidth', {
|
|
1395 value: attr.maxWidth || 10000,
|
|
1396 validator: YAHOO.lang.isNumber
|
|
1397 });
|
|
1398
|
|
1399 /**
|
|
1400 * @attribute maxHeight
|
|
1401 * @description The maximum height of the element
|
|
1402 * @type Number
|
|
1403 */
|
|
1404 this.setAttributeConfig('maxHeight', {
|
|
1405 value: attr.maxHeight || 10000,
|
|
1406 validator: YAHOO.lang.isNumber
|
|
1407 });
|
|
1408
|
|
1409 /**
|
|
1410 * @attribute minY
|
|
1411 * @description The minimum y coord of the element
|
|
1412 * @type Number
|
|
1413 */
|
|
1414 this.setAttributeConfig('minY', {
|
|
1415 value: attr.minY || false
|
|
1416 });
|
|
1417
|
|
1418 /**
|
|
1419 * @attribute minX
|
|
1420 * @description The minimum x coord of the element
|
|
1421 * @type Number
|
|
1422 */
|
|
1423 this.setAttributeConfig('minX', {
|
|
1424 value: attr.minX || false
|
|
1425 });
|
|
1426 /**
|
|
1427 * @attribute maxY
|
|
1428 * @description The max y coord of the element
|
|
1429 * @type Number
|
|
1430 */
|
|
1431 this.setAttributeConfig('maxY', {
|
|
1432 value: attr.maxY || false
|
|
1433 });
|
|
1434
|
|
1435 /**
|
|
1436 * @attribute maxX
|
|
1437 * @description The max x coord of the element
|
|
1438 * @type Number
|
|
1439 */
|
|
1440 this.setAttributeConfig('maxX', {
|
|
1441 value: attr.maxX || false
|
|
1442 });
|
|
1443
|
|
1444 /**
|
|
1445 * @attribute animate
|
|
1446 * @description Should be use animation to resize the element (can only be used if we use proxy).
|
|
1447 * @type Boolean
|
|
1448 */
|
|
1449 this.setAttributeConfig('animate', {
|
|
1450 value: attr.animate || false,
|
|
1451 validator: function(value) {
|
|
1452 var ret = true;
|
|
1453 if (!YAHOO.util.Anim) {
|
|
1454 ret = false;
|
|
1455 }
|
|
1456 return ret;
|
|
1457 }
|
|
1458 });
|
|
1459
|
|
1460 /**
|
|
1461 * @attribute animateEasing
|
|
1462 * @description The Easing to apply to the animation.
|
|
1463 * @type Object
|
|
1464 */
|
|
1465 this.setAttributeConfig('animateEasing', {
|
|
1466 value: attr.animateEasing || function() {
|
|
1467 var easing = false;
|
|
1468 if (YAHOO.util.Easing && YAHOO.util.Easing.easeOut) {
|
|
1469 easing = YAHOO.util.Easing.easeOut;
|
|
1470 }
|
|
1471 return easing;
|
|
1472 }()
|
|
1473 });
|
|
1474
|
|
1475 /**
|
|
1476 * @attribute animateDuration
|
|
1477 * @description The Duration to apply to the animation.
|
|
1478 * @type Number
|
|
1479 */
|
|
1480 this.setAttributeConfig('animateDuration', {
|
|
1481 value: attr.animateDuration || 0.5
|
|
1482 });
|
|
1483
|
|
1484 /**
|
|
1485 * @attribute proxy
|
|
1486 * @description Resize a proxy element instead of the real element.
|
|
1487 * @type Boolean
|
|
1488 */
|
|
1489 this.setAttributeConfig('proxy', {
|
|
1490 value: attr.proxy || false,
|
|
1491 validator: YAHOO.lang.isBoolean
|
|
1492 });
|
|
1493
|
|
1494 /**
|
|
1495 * @attribute ratio
|
|
1496 * @description Maintain the element's ratio when resizing.
|
|
1497 * @type Boolean
|
|
1498 */
|
|
1499 this.setAttributeConfig('ratio', {
|
|
1500 value: attr.ratio || false,
|
|
1501 validator: YAHOO.lang.isBoolean
|
|
1502 });
|
|
1503
|
|
1504 /**
|
|
1505 * @attribute ghost
|
|
1506 * @description Apply an opacity filter to the element being resized (only works with proxy).
|
|
1507 * @type Boolean
|
|
1508 */
|
|
1509 this.setAttributeConfig('ghost', {
|
|
1510 value: attr.ghost || false,
|
|
1511 validator: YAHOO.lang.isBoolean
|
|
1512 });
|
|
1513
|
|
1514 /**
|
|
1515 * @attribute draggable
|
|
1516 * @description A convienence method to make the element draggable
|
|
1517 * @type Boolean
|
|
1518 */
|
|
1519 this.setAttributeConfig('draggable', {
|
|
1520 value: attr.draggable || false,
|
|
1521 validator: YAHOO.lang.isBoolean,
|
|
1522 method: function(dd) {
|
|
1523 if (dd && this._wrap) {
|
|
1524 this._setupDragDrop();
|
|
1525 } else {
|
|
1526 if (this.dd) {
|
|
1527 D.removeClass(this._wrap, this.CSS_DRAG);
|
|
1528 this.dd.unreg();
|
|
1529 }
|
|
1530 }
|
|
1531 }
|
|
1532 });
|
|
1533
|
|
1534 /**
|
|
1535 * @attribute hover
|
|
1536 * @description Only show the handles when they are being moused over.
|
|
1537 * @type Boolean
|
|
1538 */
|
|
1539 this.setAttributeConfig('hover', {
|
|
1540 value: attr.hover || false,
|
|
1541 validator: YAHOO.lang.isBoolean
|
|
1542 });
|
|
1543
|
|
1544 /**
|
|
1545 * @attribute hiddenHandles
|
|
1546 * @description Don't show the handles, just use the cursor to the user.
|
|
1547 * @type Boolean
|
|
1548 */
|
|
1549 this.setAttributeConfig('hiddenHandles', {
|
|
1550 value: attr.hiddenHandles || false,
|
|
1551 validator: YAHOO.lang.isBoolean
|
|
1552 });
|
|
1553
|
|
1554 /**
|
|
1555 * @attribute knobHandles
|
|
1556 * @description Use the smaller handles, instead if the full size handles.
|
|
1557 * @type Boolean
|
|
1558 */
|
|
1559 this.setAttributeConfig('knobHandles', {
|
|
1560 value: attr.knobHandles || false,
|
|
1561 validator: YAHOO.lang.isBoolean
|
|
1562 });
|
|
1563
|
|
1564 /**
|
|
1565 * @attribute xTicks
|
|
1566 * @description The number of x ticks to span the resize to.
|
|
1567 * @type Number or False
|
|
1568 */
|
|
1569 this.setAttributeConfig('xTicks', {
|
|
1570 value: attr.xTicks || false
|
|
1571 });
|
|
1572
|
|
1573 /**
|
|
1574 * @attribute yTicks
|
|
1575 * @description The number of y ticks to span the resize to.
|
|
1576 * @type Number or False
|
|
1577 */
|
|
1578 this.setAttributeConfig('yTicks', {
|
|
1579 value: attr.yTicks || false
|
|
1580 });
|
|
1581
|
|
1582 /**
|
|
1583 * @attribute status
|
|
1584 * @description Show the status (new size) of the resize.
|
|
1585 * @type Boolean
|
|
1586 */
|
|
1587 this.setAttributeConfig('status', {
|
|
1588 value: attr.status || false,
|
|
1589 validator: YAHOO.lang.isBoolean
|
|
1590 });
|
|
1591
|
|
1592 /**
|
|
1593 * @attribute autoRatio
|
|
1594 * @description Using the shift key during a resize will toggle the ratio config.
|
|
1595 * @type Boolean
|
|
1596 */
|
|
1597 this.setAttributeConfig('autoRatio', {
|
|
1598 value: attr.autoRatio || false,
|
|
1599 validator: YAHOO.lang.isBoolean
|
|
1600 });
|
|
1601
|
|
1602 },
|
|
1603 /**
|
|
1604 * @method destroy
|
|
1605 * @description Destroys the resize object and all of it's elements & listeners.
|
|
1606 */
|
|
1607 destroy: function() {
|
|
1608 for (var h in this._handles) {
|
|
1609 if (Lang.hasOwnProperty(this._handles, h)) {
|
|
1610 Event.purgeElement(this._handles[h]);
|
|
1611 this._handles[h].parentNode.removeChild(this._handles[h]);
|
|
1612 }
|
|
1613 }
|
|
1614 if (this._proxy) {
|
|
1615 this._proxy.parentNode.removeChild(this._proxy);
|
|
1616 }
|
|
1617 if (this._status) {
|
|
1618 this._status.parentNode.removeChild(this._status);
|
|
1619 }
|
|
1620 if (this.dd) {
|
|
1621 this.dd.unreg();
|
|
1622 D.removeClass(this._wrap, this.CSS_DRAG);
|
|
1623 }
|
|
1624 if (this._wrap != this.get('element')) {
|
|
1625 this.setStyle('position', '');
|
|
1626 this.setStyle('top', '');
|
|
1627 this.setStyle('left', '');
|
|
1628 this._wrap.parentNode.replaceChild(this.get('element'), this._wrap);
|
|
1629 }
|
|
1630 this.removeClass(this.CSS_RESIZE);
|
|
1631
|
|
1632 delete YAHOO.util.Resize._instances[this.get('id')];
|
|
1633 //Brutal Object Destroy
|
|
1634 for (var i in this) {
|
|
1635 if (Lang.hasOwnProperty(this, i)) {
|
|
1636 this[i] = null;
|
|
1637 delete this[i];
|
|
1638 }
|
|
1639 }
|
|
1640 },
|
|
1641 /**
|
|
1642 * @method toString
|
|
1643 * @description Returns a string representing the Resize Object.
|
|
1644 * @return {String}
|
|
1645 */
|
|
1646 toString: function() {
|
|
1647 if (this.get) {
|
|
1648 return 'Resize (#' + this.get('id') + ')';
|
|
1649 }
|
|
1650 return 'Resize Utility';
|
|
1651 }
|
|
1652 });
|
|
1653
|
|
1654 YAHOO.util.Resize = Resize;
|
|
1655
|
|
1656 /**
|
|
1657 * @event dragEvent
|
|
1658 * @description Fires when the <a href="YAHOO.util.DragDrop.html">YAHOO.util.DragDrop</a> dragEvent is fired for the config option draggable.
|
|
1659 * @type YAHOO.util.CustomEvent
|
|
1660 */
|
|
1661 /**
|
|
1662 * @event startResize
|
|
1663 * @description Fires when a resize action is started.
|
|
1664 * @type YAHOO.util.CustomEvent
|
|
1665 */
|
|
1666 /**
|
|
1667 * @event endResize
|
|
1668 * @description Fires when the mouseUp event from the Drag Instance fires.
|
|
1669 * @type YAHOO.util.CustomEvent
|
|
1670 */
|
|
1671 /**
|
|
1672 * @event resize
|
|
1673 * @description Fires on every element resize (only fires once when used with proxy config setting).
|
|
1674 * @type YAHOO.util.CustomEvent
|
|
1675 */
|
|
1676 /**
|
|
1677 * @event beforeResize
|
|
1678 * @description Fires before every element resize after the size calculations, returning false will stop the resize.
|
|
1679 * @type YAHOO.util.CustomEvent
|
|
1680 */
|
|
1681 /**
|
|
1682 * @event proxyResize
|
|
1683 * @description Fires on every proxy resize (only fires when used with proxy config setting).
|
|
1684 * @type YAHOO.util.CustomEvent
|
|
1685 */
|
|
1686
|
|
1687 })();
|
|
1688
|
|
1689 YAHOO.register("resize", YAHOO.util.Resize, {version: "2.8.0r4", build: "2449"});
|