/hippo/src/main/webapp/yui/resize/resize-debug.js

http://hdbc.googlecode.com/ · JavaScript · 1702 lines · 1043 code · 75 blank · 584 comment · 235 complexity · 82b1f4bc7164eec3dd4fffd26bb1f749 MD5 · raw file

Large files are truncated click here to view the full file

  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.7.0
  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. * @constructor
  20. * @class Resize
  21. * @extends YAHOO.util.Element
  22. * @description <p>Makes an element resizable</p>
  23. * @param {String/HTMLElement} el The element to make resizable.
  24. * @param {Object} attrs Object liternal containing configuration parameters.
  25. */
  26. var Resize = function(el, config) {
  27. YAHOO.log('Creating Resize Object', 'info', 'Resize');
  28. var oConfig = {
  29. element: el,
  30. attributes: config || {}
  31. };
  32. Resize.superclass.constructor.call(this, oConfig.element, oConfig.attributes);
  33. };
  34. /**
  35. * @private
  36. * @static
  37. * @property _instances
  38. * @description Internal hash table for all resize instances
  39. * @type Object
  40. */
  41. Resize._instances = {};
  42. /**
  43. * @static
  44. * @method getResizeById
  45. * @description Get's a resize object by the HTML id of the element associated with the Resize object.
  46. * @return {Object} The Resize Object
  47. */
  48. Resize.getResizeById = function(id) {
  49. if (Resize._instances[id]) {
  50. return Resize._instances[id];
  51. }
  52. YAHOO.log('No Instance Found', 'error', 'Resize');
  53. return false;
  54. };
  55. YAHOO.extend(Resize, YAHOO.util.Element, {
  56. /**
  57. * @private
  58. * @property CSS_RESIZE
  59. * @description Base CSS class name
  60. * @type String
  61. */
  62. CSS_RESIZE: 'yui-resize',
  63. /**
  64. * @private
  65. * @property CSS_DRAG
  66. * @description Class name added when dragging is enabled
  67. * @type String
  68. */
  69. CSS_DRAG: 'yui-draggable',
  70. /**
  71. * @private
  72. * @property CSS_HOVER
  73. * @description Class name used for hover only handles
  74. * @type String
  75. */
  76. CSS_HOVER: 'yui-resize-hover',
  77. /**
  78. * @private
  79. * @property CSS_PROXY
  80. * @description Class name given to the proxy element
  81. * @type String
  82. */
  83. CSS_PROXY: 'yui-resize-proxy',
  84. /**
  85. * @private
  86. * @property CSS_WRAP
  87. * @description Class name given to the wrap element
  88. * @type String
  89. */
  90. CSS_WRAP: 'yui-resize-wrap',
  91. /**
  92. * @private
  93. * @property CSS_KNOB
  94. * @description Class name used to make the knob style handles
  95. * @type String
  96. */
  97. CSS_KNOB: 'yui-resize-knob',
  98. /**
  99. * @private
  100. * @property CSS_HIDDEN
  101. * @description Class name given to the wrap element to make all handles hidden
  102. * @type String
  103. */
  104. CSS_HIDDEN: 'yui-resize-hidden',
  105. /**
  106. * @private
  107. * @property CSS_HANDLE
  108. * @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
  109. * @type String
  110. */
  111. CSS_HANDLE: 'yui-resize-handle',
  112. /**
  113. * @private
  114. * @property CSS_STATUS
  115. * @description Class name given to the status element
  116. * @type String
  117. */
  118. CSS_STATUS: 'yui-resize-status',
  119. /**
  120. * @private
  121. * @property CSS_GHOST
  122. * @description Class name given to the wrap element when the ghost property is active
  123. * @type String
  124. */
  125. CSS_GHOST: 'yui-resize-ghost',
  126. /**
  127. * @private
  128. * @property CSS_RESIZING
  129. * @description Class name given to the wrap element when a resize action is taking place.
  130. * @type String
  131. */
  132. CSS_RESIZING: 'yui-resize-resizing',
  133. /**
  134. * @private
  135. * @property _resizeEvent
  136. * @description The mouse event used to resize with
  137. * @type Event
  138. */
  139. _resizeEvent: null,
  140. /**
  141. * @private
  142. * @property dd
  143. * @description The <a href="YAHOO.util.DragDrop.html">YAHOO.util.DragDrop</a> instance used if draggable is true
  144. * @type Object
  145. */
  146. dd: null,
  147. /**
  148. * @private
  149. * @property browser
  150. * @description A copy of the YAHOO.env.ua property
  151. * @type Object
  152. */
  153. browser: YAHOO.env.ua,
  154. /**
  155. * @private
  156. * @property _locked
  157. * @description A flag to show if the resize is locked
  158. * @type Boolean
  159. */
  160. _locked: null,
  161. /**
  162. * @private
  163. * @property _positioned
  164. * @description A flag to show if the element is absolutely positioned
  165. * @type Boolean
  166. */
  167. _positioned: null,
  168. /**
  169. * @private
  170. * @property _dds
  171. * @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
  172. * @type Object
  173. */
  174. _dds: null,
  175. /**
  176. * @private
  177. * @property _wrap
  178. * @description The HTML reference of the element wrapper
  179. * @type HTMLElement
  180. */
  181. _wrap: null,
  182. /**
  183. * @private
  184. * @property _proxy
  185. * @description The HTML reference of the element proxy
  186. * @type HTMLElement
  187. */
  188. _proxy: null,
  189. /**
  190. * @private
  191. * @property _handles
  192. * @description An object containing references to all of the resize handles.
  193. * @type Object
  194. */
  195. _handles: null,
  196. /**
  197. * @private
  198. * @property _currentHandle
  199. * @description The string identifier of the currently active handle. e.g. 'r', 'br', 'tl'
  200. * @type String
  201. */
  202. _currentHandle: null,
  203. /**
  204. * @private
  205. * @property _currentDD
  206. * @description A link to the currently active DD object
  207. * @type Object
  208. */
  209. _currentDD: null,
  210. /**
  211. * @private
  212. * @property _cache
  213. * @description An lookup table containing key information for the element being resized. e.g. height, width, x position, y position, etc..
  214. * @type Object
  215. */
  216. _cache: null,
  217. /**
  218. * @private
  219. * @property _active
  220. * @description Flag to show if the resize is active. Used for events.
  221. * @type Boolean
  222. */
  223. _active: null,
  224. /**
  225. * @private
  226. * @method _createProxy
  227. * @description Creates the proxy element if the proxy config is true
  228. */
  229. _createProxy: function() {
  230. if (this.get('proxy')) {
  231. YAHOO.log('Creating the Proxy Element', 'info', 'Resize');
  232. this._proxy = document.createElement('div');
  233. this._proxy.className = this.CSS_PROXY;
  234. this._proxy.style.height = this.get('element').clientHeight + 'px';
  235. this._proxy.style.width = this.get('element').clientWidth + 'px';
  236. this._wrap.parentNode.appendChild(this._proxy);
  237. } else {
  238. YAHOO.log('No proxy element, turn off animate config option', 'info', 'Resize');
  239. this.set('animate', false);
  240. }
  241. },
  242. /**
  243. * @private
  244. * @method _createWrap
  245. * @description Creates the wrap element if the wrap config is true. It will auto wrap the following element types: img, textarea, input, iframe, select
  246. */
  247. _createWrap: function() {
  248. YAHOO.log('Create the wrap element', 'info', 'Resize');
  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. YAHOO.log('Auto-wrapping the element (' + this.get('element').tagName.toLowerCase() + ')', 'warn', 'Resize');
  259. this.set('wrap', true);
  260. break;
  261. }
  262. }
  263. if (this.get('wrap') === true) {
  264. YAHOO.log('Creating the wrap element', 'info', 'Resize');
  265. this._wrap = document.createElement('div');
  266. this._wrap.id = this.get('element').id + '_wrap';
  267. this._wrap.className = this.CSS_WRAP;
  268. if (this.get('element').tagName.toLowerCase() == 'textarea') {
  269. D.addClass(this._wrap, 'yui-resize-textarea');
  270. }
  271. D.setStyle(this._wrap, 'width', this.get('width') + 'px');
  272. D.setStyle(this._wrap, 'height', this.get('height') + 'px');
  273. D.setStyle(this._wrap, 'z-index', this.getStyle('z-index'));
  274. this.setStyle('z-index', 0);
  275. var pos = D.getStyle(this.get('element'), 'position');
  276. D.setStyle(this._wrap, 'position', ((pos == 'static') ? 'relative' : pos));
  277. D.setStyle(this._wrap, 'top', D.getStyle(this.get('element'), 'top'));
  278. D.setStyle(this._wrap, 'left', D.getStyle(this.get('element'), 'left'));
  279. if (D.getStyle(this.get('element'), 'position') == 'absolute') {
  280. this._positioned = true;
  281. YAHOO.log('The element is positioned absolute', 'info', 'Resize');
  282. D.setStyle(this.get('element'), 'position', 'relative');
  283. D.setStyle(this.get('element'), 'top', '0');
  284. D.setStyle(this.get('element'), 'left', '0');
  285. }
  286. var par = this.get('element').parentNode;
  287. par.replaceChild(this._wrap, this.get('element'));
  288. this._wrap.appendChild(this.get('element'));
  289. } else {
  290. this._wrap = this.get('element');
  291. if (D.getStyle(this._wrap, 'position') == 'absolute') {
  292. this._positioned = true;
  293. }
  294. }
  295. if (this.get('draggable')) {
  296. this._setupDragDrop();
  297. }
  298. if (this.get('hover')) {
  299. D.addClass(this._wrap, this.CSS_HOVER);
  300. }
  301. if (this.get('knobHandles')) {
  302. D.addClass(this._wrap, this.CSS_KNOB);
  303. }
  304. if (this.get('hiddenHandles')) {
  305. D.addClass(this._wrap, this.CSS_HIDDEN);
  306. }
  307. D.addClass(this._wrap, this.CSS_RESIZE);
  308. },
  309. /**
  310. * @private
  311. * @method _setupDragDrop
  312. * @description Setup the <a href="YAHOO.util.DragDrop.html">YAHOO.util.DragDrop</a> instance on the element
  313. */
  314. _setupDragDrop: function() {
  315. YAHOO.log('Setting up the dragdrop instance on the element', 'info', 'Resize');
  316. D.addClass(this._wrap, this.CSS_DRAG);
  317. this.dd = new YAHOO.util.DD(this._wrap, this.get('id') + '-resize', { dragOnly: true, useShim: this.get('useShim') });
  318. this.dd.on('dragEvent', function() {
  319. this.fireEvent('dragEvent', arguments);
  320. }, this, true);
  321. },
  322. /**
  323. * @private
  324. * @method _createHandles
  325. * @description Creates the handles as specified in the config
  326. */
  327. _createHandles: function() {
  328. YAHOO.log('Creating the handles', 'info', 'Resize');
  329. this._handles = {};
  330. this._dds = {};
  331. var h = this.get('handles');
  332. for (var i = 0; i < h.length; i++) {
  333. YAHOO.log('Creating handle position: ' + h[i], 'info', 'Resize');
  334. this._handles[h[i]] = document.createElement('div');
  335. this._handles[h[i]].id = D.generateId(this._handles[h[i]]);
  336. this._handles[h[i]].className = this.CSS_HANDLE + ' ' + this.CSS_HANDLE + '-' + h[i];
  337. var k = document.createElement('div');
  338. k.className = this.CSS_HANDLE + '-inner-' + h[i];
  339. this._handles[h[i]].appendChild(k);
  340. this._wrap.appendChild(this._handles[h[i]]);
  341. Event.on(this._handles[h[i]], 'mouseover', this._handleMouseOver, this, true);
  342. Event.on(this._handles[h[i]], 'mouseout', this._handleMouseOut, this, true);
  343. this._dds[h[i]] = new YAHOO.util.DragDrop(this._handles[h[i]], this.get('id') + '-handle-' + h, { useShim: this.get('useShim') });
  344. this._dds[h[i]].setPadding(15, 15, 15, 15);
  345. this._dds[h[i]].on('startDragEvent', this._handleStartDrag, this._dds[h[i]], this);
  346. this._dds[h[i]].on('mouseDownEvent', this._handleMouseDown, this._dds[h[i]], this);
  347. }
  348. YAHOO.log('Creating the Status box', 'info', 'Resize');
  349. this._status = document.createElement('span');
  350. this._status.className = this.CSS_STATUS;
  351. document.body.insertBefore(this._status, document.body.firstChild);
  352. },
  353. /**
  354. * @private
  355. * @method _ieSelectFix
  356. * @description The function we use as the onselectstart handler when we start a drag in Internet Explorer
  357. */
  358. _ieSelectFix: function() {
  359. return false;
  360. },
  361. /**
  362. * @private
  363. * @property _ieSelectBack
  364. * @description We will hold a copy of the current "onselectstart" method on this property, and reset it after we are done using it.
  365. */
  366. _ieSelectBack: null,
  367. /**
  368. * @private
  369. * @method _setAutoRatio
  370. * @param {Event} ev A mouse event.
  371. * @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.
  372. */
  373. _setAutoRatio: function(ev) {
  374. if (this.get('autoRatio')) {
  375. YAHOO.log('Setting up AutoRatio', 'info', 'Resize');
  376. if (ev && ev.shiftKey) {
  377. //Shift Pressed
  378. YAHOO.log('Shift key presses, turning on ratio', 'info', 'Resize');
  379. this.set('ratio', true);
  380. } else {
  381. YAHOO.log('Resetting ratio back to default', 'info', 'Resize');
  382. this.set('ratio', this._configs.ratio._initialConfig.value);
  383. }
  384. }
  385. },
  386. /**
  387. * @private
  388. * @method _handleMouseDown
  389. * @param {Event} ev A mouse event.
  390. * @description This method preps the autoRatio on MouseDown.
  391. */
  392. _handleMouseDown: function(ev) {
  393. if (this._locked) {
  394. YAHOO.log('Resize Locked', 'info', 'Resize');
  395. return false;
  396. }
  397. if (D.getStyle(this._wrap, 'position') == 'absolute') {
  398. this._positioned = true;
  399. }
  400. if (ev) {
  401. this._setAutoRatio(ev);
  402. }
  403. if (this.browser.ie) {
  404. this._ieSelectBack = document.body.onselectstart;
  405. document.body.onselectstart = this._ieSelectFix;
  406. }
  407. },
  408. /**
  409. * @private
  410. * @method _handleMouseOver
  411. * @param {Event} ev A mouse event.
  412. * @description Adds CSS class names to the handles
  413. */
  414. _handleMouseOver: function(ev) {
  415. if (this._locked) {
  416. YAHOO.log('Resize Locked', 'info', 'Resize');
  417. return false;
  418. }
  419. D.removeClass(this._wrap, this.CSS_RESIZE);
  420. if (this.get('hover')) {
  421. D.removeClass(this._wrap, this.CSS_HOVER);
  422. }
  423. var tar = Event.getTarget(ev);
  424. if (!D.hasClass(tar, this.CSS_HANDLE)) {
  425. tar = tar.parentNode;
  426. }
  427. if (D.hasClass(tar, this.CSS_HANDLE) && !this._active) {
  428. D.addClass(tar, this.CSS_HANDLE + '-active');
  429. for (var i in this._handles) {
  430. if (Lang.hasOwnProperty(this._handles, i)) {
  431. if (this._handles[i] == tar) {
  432. D.addClass(tar, this.CSS_HANDLE + '-' + i + '-active');
  433. break;
  434. }
  435. }
  436. }
  437. }
  438. D.addClass(this._wrap, this.CSS_RESIZE);
  439. },
  440. /**
  441. * @private
  442. * @method _handleMouseOut
  443. * @param {Event} ev A mouse event.
  444. * @description Removes CSS class names to the handles
  445. */
  446. _handleMouseOut: function(ev) {
  447. D.removeClass(this._wrap, this.CSS_RESIZE);
  448. if (this.get('hover') && !this._active) {
  449. D.addClass(this._wrap, this.CSS_HOVER);
  450. }
  451. var tar = Event.getTarget(ev);
  452. if (!D.hasClass(tar, this.CSS_HANDLE)) {
  453. tar = tar.parentNode;
  454. }
  455. if (D.hasClass(tar, this.CSS_HANDLE) && !this._active) {
  456. D.removeClass(tar, this.CSS_HANDLE + '-active');
  457. for (var i in this._handles) {
  458. if (Lang.hasOwnProperty(this._handles, i)) {
  459. if (this._handles[i] == tar) {
  460. D.removeClass(tar, this.CSS_HANDLE + '-' + i + '-active');
  461. break;
  462. }
  463. }
  464. }
  465. }
  466. D.addClass(this._wrap, this.CSS_RESIZE);
  467. },
  468. /**
  469. * @private
  470. * @method _handleStartDrag
  471. * @param {Object} args The args passed from the CustomEvent.
  472. * @param {Object} dd The <a href="YAHOO.util.DragDrop.html">YAHOO.util.DragDrop</a> object we are working with.
  473. * @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
  474. */
  475. _handleStartDrag: function(args, dd) {
  476. YAHOO.log('startDrag', 'info', 'Resize');
  477. var tar = dd.getDragEl();
  478. if (D.hasClass(tar, this.CSS_HANDLE)) {
  479. if (D.getStyle(this._wrap, 'position') == 'absolute') {
  480. this._positioned = true;
  481. }
  482. this._active = true;
  483. this._currentDD = dd;
  484. if (this._proxy) {
  485. YAHOO.log('Activate proxy element', 'info', 'Resize');
  486. this._proxy.style.visibility = 'visible';
  487. this._proxy.style.zIndex = '1000';
  488. this._proxy.style.height = this.get('element').clientHeight + 'px';
  489. this._proxy.style.width = this.get('element').clientWidth + 'px';
  490. }
  491. for (var i in this._handles) {
  492. if (Lang.hasOwnProperty(this._handles, i)) {
  493. if (this._handles[i] == tar) {
  494. this._currentHandle = i;
  495. var handle = '_handle_for_' + i;
  496. D.addClass(tar, this.CSS_HANDLE + '-' + i + '-active');
  497. dd.on('dragEvent', this[handle], this, true);
  498. dd.on('mouseUpEvent', this._handleMouseUp, this, true);
  499. YAHOO.log('Adding DragEvents to: ' + i, 'info', 'Resize');
  500. break;
  501. }
  502. }
  503. }
  504. D.addClass(tar, this.CSS_HANDLE + '-active');
  505. if (this.get('proxy')) {
  506. YAHOO.log('Posiiton Proxy Element', 'info', 'Resize');
  507. var xy = D.getXY(this.get('element'));
  508. D.setXY(this._proxy, xy);
  509. if (this.get('ghost')) {
  510. YAHOO.log('Add Ghost Class', 'info', 'Resize');
  511. this.addClass(this.CSS_GHOST);
  512. }
  513. }
  514. D.addClass(this._wrap, this.CSS_RESIZING);
  515. this._setCache();
  516. this._updateStatus(this._cache.height, this._cache.width, this._cache.top, this._cache.left);
  517. YAHOO.log('Firing startResize Event', 'info', 'Resize');
  518. this.fireEvent('startResize', { type: 'startresize', target: this});
  519. }
  520. },
  521. /**
  522. * @private
  523. * @method _setCache
  524. * @description Sets up the this._cache hash table.
  525. */
  526. _setCache: function() {
  527. YAHOO.log('Setting up property cache', 'info', 'Resize');
  528. this._cache.xy = D.getXY(this._wrap);
  529. D.setXY(this._wrap, this._cache.xy);
  530. this._cache.height = this.get('clientHeight');
  531. this._cache.width = this.get('clientWidth');
  532. this._cache.start.height = this._cache.height;
  533. this._cache.start.width = this._cache.width;
  534. this._cache.start.top = this._cache.xy[1];
  535. this._cache.start.left = this._cache.xy[0];
  536. this._cache.top = this._cache.xy[1];
  537. this._cache.left = this._cache.xy[0];
  538. this.set('height', this._cache.height, true);
  539. this.set('width', this._cache.width, true);
  540. },
  541. /**
  542. * @private
  543. * @method _handleMouseUp
  544. * @param {Event} ev A mouse event.
  545. * @description Cleans up listeners, hides proxy element and removes class names.
  546. */
  547. _handleMouseUp: function(ev) {
  548. this._active = false;
  549. var handle = '_handle_for_' + this._currentHandle;
  550. this._currentDD.unsubscribe('dragEvent', this[handle], this, true);
  551. this._currentDD.unsubscribe('mouseUpEvent', this._handleMouseUp, this, true);
  552. if (this._proxy) {
  553. YAHOO.log('Hide Proxy Element', 'info', 'Resize');
  554. this._proxy.style.visibility = 'hidden';
  555. this._proxy.style.zIndex = '-1';
  556. if (this.get('setSize')) {
  557. YAHOO.log('Setting Size', 'info', 'Resize');
  558. this.resize(ev, this._cache.height, this._cache.width, this._cache.top, this._cache.left, true);
  559. } else {
  560. YAHOO.log('Firing Resize Event', 'info', 'Resize');
  561. this.fireEvent('resize', { ev: 'resize', target: this, height: this._cache.height, width: this._cache.width, top: this._cache.top, left: this._cache.left });
  562. }
  563. if (this.get('ghost')) {
  564. YAHOO.log('Removing Ghost Class', 'info', 'Resize');
  565. this.removeClass(this.CSS_GHOST);
  566. }
  567. }
  568. if (this.get('hover')) {
  569. D.addClass(this._wrap, this.CSS_HOVER);
  570. }
  571. if (this._status) {
  572. D.setStyle(this._status, 'display', 'none');
  573. }
  574. if (this.browser.ie) {
  575. YAHOO.log('Resetting IE onselectstart function', 'info', 'Resize');
  576. document.body.onselectstart = this._ieSelectBack;
  577. }
  578. if (this.browser.ie) {
  579. D.removeClass(this._wrap, this.CSS_RESIZE);
  580. }
  581. for (var i in this._handles) {
  582. if (Lang.hasOwnProperty(this._handles, i)) {
  583. D.removeClass(this._handles[i], this.CSS_HANDLE + '-active');
  584. }
  585. }
  586. if (this.get('hover') && !this._active) {
  587. D.addClass(this._wrap, this.CSS_HOVER);
  588. }
  589. D.removeClass(this._wrap, this.CSS_RESIZING);
  590. D.removeClass(this._handles[this._currentHandle], this.CSS_HANDLE + '-' + this._currentHandle + '-active');
  591. D.removeClass(this._handles[this._currentHandle], this.CSS_HANDLE + '-active');
  592. if (this.browser.ie) {
  593. D.addClass(this._wrap, this.CSS_RESIZE);
  594. }
  595. this._resizeEvent = null;
  596. this._currentHandle = null;
  597. if (!this.get('animate')) {
  598. this.set('height', this._cache.height, true);
  599. this.set('width', this._cache.width, true);
  600. }
  601. YAHOO.log('Firing endResize Event', 'info', 'Resize');
  602. this.fireEvent('endResize', { ev: 'endResize', target: this, height: this._cache.height, width: this._cache.width, top: this._cache.top, left: this._cache.left });
  603. },
  604. /**
  605. * @private
  606. * @method _setRatio
  607. * @param {Number} h The height offset.
  608. * @param {Number} w The with offset.
  609. * @param {Number} t The top offset.
  610. * @param {Number} l The left offset.
  611. * @description Using the Height, Width, Top & Left, it recalcuates them based on the original element size.
  612. * @return {Array} The new Height, Width, Top & Left settings
  613. */
  614. _setRatio: function(h, w, t, l) {
  615. YAHOO.log('Setting Ratio', 'info', 'Resize');
  616. var oh = h, ow = w;
  617. if (this.get('ratio')) {
  618. var orgH = this._cache.height,
  619. orgW = this._cache.width,
  620. nh = parseInt(this.get('height'), 10),
  621. nw = parseInt(this.get('width'), 10),
  622. maxH = this.get('maxHeight'),
  623. minH = this.get('minHeight'),
  624. maxW = this.get('maxWidth'),
  625. minW = this.get('minWidth');
  626. switch (this._currentHandle) {
  627. case 'l':
  628. h = nh * (w / nw);
  629. h = Math.min(Math.max(minH, h), maxH);
  630. w = nw * (h / nh);
  631. t = (this._cache.start.top - (-((nh - h) / 2)));
  632. l = (this._cache.start.left - (-((nw - w))));
  633. break;
  634. case 'r':
  635. h = nh * (w / nw);
  636. h = Math.min(Math.max(minH, h), maxH);
  637. w = nw * (h / nh);
  638. t = (this._cache.start.top - (-((nh - h) / 2)));
  639. break;
  640. case 't':
  641. w = nw * (h / nh);
  642. h = nh * (w / nw);
  643. l = (this._cache.start.left - (-((nw - w) / 2)));
  644. t = (this._cache.start.top - (-((nh - h))));
  645. break;
  646. case 'b':
  647. w = nw * (h / nh);
  648. h = nh * (w / nw);
  649. l = (this._cache.start.left - (-((nw - w) / 2)));
  650. break;
  651. case 'bl':
  652. h = nh * (w / nw);
  653. w = nw * (h / nh);
  654. l = (this._cache.start.left - (-((nw - w))));
  655. break;
  656. case 'br':
  657. h = nh * (w / nw);
  658. w = nw * (h / nh);
  659. break;
  660. case 'tl':
  661. h = nh * (w / nw);
  662. w = nw * (h / nh);
  663. l = (this._cache.start.left - (-((nw - w))));
  664. t = (this._cache.start.top - (-((nh - h))));
  665. break;
  666. case 'tr':
  667. h = nh * (w / nw);
  668. w = nw * (h / nh);
  669. l = (this._cache.start.left);
  670. t = (this._cache.start.top - (-((nh - h))));
  671. break;
  672. }
  673. oh = this._checkHeight(h);
  674. ow = this._checkWidth(w);
  675. if ((oh != h) || (ow != w)) {
  676. t = 0;
  677. l = 0;
  678. if (oh != h) {
  679. ow = this._cache.width;
  680. }
  681. if (ow != w) {
  682. oh = this._cache.height;
  683. }
  684. }
  685. }
  686. return [oh, ow, t, l];
  687. },
  688. /**
  689. * @private
  690. * @method _updateStatus
  691. * @param {Number} h The new height setting.
  692. * @param {Number} w The new width setting.
  693. * @param {Number} t The new top setting.
  694. * @param {Number} l The new left setting.
  695. * @description Using the Height, Width, Top & Left, it updates the status element with the elements sizes.
  696. */
  697. _updateStatus: function(h, w, t, l) {
  698. if (this._resizeEvent && (!Lang.isString(this._resizeEvent))) {
  699. YAHOO.log('Updating Status Box', 'info', 'Resize');
  700. h = ((h === 0) ? this._cache.start.height : h);
  701. w = ((w === 0) ? this._cache.start.width : w);
  702. var h1 = parseInt(this.get('height'), 10),
  703. w1 = parseInt(this.get('width'), 10);
  704. if (isNaN(h1)) {
  705. h1 = parseInt(h, 10);
  706. }
  707. if (isNaN(w1)) {
  708. w1 = parseInt(w, 10);
  709. }
  710. var diffH = (parseInt(h, 10) - h1);
  711. var diffW = (parseInt(w, 10) - w1);
  712. this._cache.offsetHeight = diffH;
  713. this._cache.offsetWidth = diffW;
  714. if (this.get('status')) {
  715. YAHOO.log('Showing Status Box', 'info', 'Resize');
  716. D.setStyle(this._status, 'display', 'inline');
  717. //This will cause IE8 to crash if the status box is hidden..
  718. this._status.innerHTML = '<strong>' + parseInt(h, 10) + ' x ' + parseInt(w, 10) + '</strong><em>' + ((diffH > 0) ? '+' : '') + diffH + ' x ' + ((diffW > 0) ? '+' : '') + diffW + '</em>';
  719. D.setXY(this._status, [Event.getPageX(this._resizeEvent) + 12, Event.getPageY(this._resizeEvent) + 12]);
  720. }
  721. }
  722. },
  723. /**
  724. * @method lock
  725. * @description Lock the resize so it can't be resized
  726. * @param {Boolean} dd If the draggable config is set, lock it too
  727. * @return {<a href="YAHOO.util.Resize.html">YAHOO.util.Resize</a>} The Resize instance
  728. */
  729. lock: function(dd) {
  730. this._locked = true;
  731. if (dd && this.dd) {
  732. D.removeClass(this._wrap, 'yui-draggable');
  733. this.dd.lock();
  734. }
  735. return this;
  736. },
  737. /**
  738. * @method unlock
  739. * @description Unlock the resize so it can be resized
  740. * @param {Boolean} dd If the draggable config is set, unlock it too
  741. * @return {<a href="YAHOO.util.Resize.html">YAHOO.util.Resize</a>} The Resize instance
  742. */
  743. unlock: function(dd) {
  744. this._locked = false;
  745. if (dd && this.dd) {
  746. D.addClass(this._wrap, 'yui-draggable');
  747. this.dd.unlock();
  748. }
  749. return this;
  750. },
  751. /**
  752. * @method isLocked
  753. * @description Check the locked status of the resize instance
  754. * @return {Boolean}
  755. */
  756. isLocked: function() {
  757. return this._locked;
  758. },
  759. /**
  760. * @method reset
  761. * @description Resets the element to is start state.
  762. * @return {<a href="YAHOO.util.Resize.html">YAHOO.util.Resize</a>} The Resize instance
  763. */
  764. reset: function() {
  765. YAHOO.log('Resetting to cached sizes and position', 'info', 'Resize');
  766. this.resize(null, this._cache.start.height, this._cache.start.width, this._cache.start.top, this._cache.start.left, true);
  767. return this;
  768. },
  769. /**
  770. * @private
  771. * @method resize
  772. * @param {Event} ev The mouse event.
  773. * @param {Number} h The new height setting.
  774. * @param {Number} w The new width setting.
  775. * @param {Number} t The new top setting.
  776. * @param {Number} l The new left setting.
  777. * @param {Boolean} force Resize the element (used for proxy resize).
  778. * @param {Boolean} silent Don't fire the beforeResize Event.
  779. * @description Resizes the element, wrapper or proxy based on the data from the handlers.
  780. * @return {<a href="YAHOO.util.Resize.html">YAHOO.util.Resize</a>} The Resize instance
  781. */
  782. resize: function(ev, h, w, t, l, force, silent) {
  783. if (this._locked) {
  784. YAHOO.log('Resize Locked', 'info', 'Resize');
  785. return false;
  786. }
  787. YAHOO.log('Resize: ' + h + ',' + w + ',' + t + ',' + l, 'info', 'Resize');
  788. this._resizeEvent = ev;
  789. var el = this._wrap, anim = this.get('animate'), set = true;
  790. if (this._proxy && !force) {
  791. el = this._proxy;
  792. anim = false;
  793. }
  794. this._setAutoRatio(ev);
  795. if (this._positioned) {
  796. if (this._proxy) {
  797. t = this._cache.top - t;
  798. l = this._cache.left - l;
  799. }
  800. }
  801. var ratio = this._setRatio(h, w, t, l);
  802. h = parseInt(ratio[0], 10);
  803. w = parseInt(ratio[1], 10);
  804. t = parseInt(ratio[2], 10);
  805. l = parseInt(ratio[3], 10);
  806. if (t == 0) {
  807. //No Offset, get from cache
  808. t = D.getY(el);
  809. }
  810. if (l == 0) {
  811. //No Offset, get from cache
  812. l = D.getX(el);
  813. }
  814. if (this._positioned) {
  815. if (this._proxy && force) {
  816. if (!anim) {
  817. el.style.top = this._proxy.style.top;
  818. el.style.left = this._proxy.style.left;
  819. } else {
  820. t = this._proxy.style.top;
  821. l = this._proxy.style.left;
  822. }
  823. } else {
  824. if (!this.get('ratio') && !this._proxy) {
  825. t = this._cache.top + -(t);
  826. l = this._cache.left + -(l);
  827. }
  828. if (t) {
  829. if (this.get('minY')) {
  830. if (t < this.get('minY')) {
  831. t = this.get('minY');
  832. }
  833. }
  834. if (this.get('maxY')) {
  835. if (t > this.get('maxY')) {
  836. t = this.get('maxY');
  837. }
  838. }
  839. }
  840. if (l) {
  841. if (this.get('minX')) {
  842. if (l < this.get('minX')) {
  843. l = this.get('minX');
  844. }
  845. }
  846. if (this.get('maxX')) {
  847. if ((l + w) > this.get('maxX')) {
  848. l = (this.get('maxX') - w);
  849. }
  850. }
  851. }
  852. }
  853. }
  854. if (!silent) {
  855. YAHOO.log('beforeResize', 'info', 'Resize');
  856. var beforeReturn = this.fireEvent('beforeResize', { ev: 'beforeResize', target: this, height: h, width: w, top: t, left: l });
  857. if (beforeReturn === false) {
  858. YAHOO.log('Resized cancelled because befireResize returned false', 'info', 'Resize');
  859. return false;
  860. }
  861. }
  862. this._updateStatus(h, w, t, l);
  863. if (this._positioned) {
  864. if (this._proxy && force) {
  865. //Do nothing
  866. } else {
  867. if (t) {
  868. D.setY(el, t);
  869. this._cache.top = t;
  870. }
  871. if (l) {
  872. D.setX(el, l);
  873. this._cache.left = l;
  874. }
  875. }
  876. }
  877. if (h) {
  878. if (!anim) {
  879. set = true;
  880. if (this._proxy && force) {
  881. if (!this.get('setSize')) {
  882. set = false;
  883. }
  884. }
  885. if (set) {
  886. el.style.height = h + 'px';
  887. }
  888. if ((this._proxy && force) || !this._proxy) {
  889. if (this._wrap != this.get('element')) {
  890. this.get('element').style.height = h + 'px';
  891. }
  892. }
  893. }
  894. this._cache.height = h;
  895. }
  896. if (w) {
  897. this._cache.width = w;
  898. if (!anim) {
  899. set = true;
  900. if (this._proxy && force) {
  901. if (!this.get('setSize')) {
  902. set = false;
  903. }
  904. }
  905. if (set) {
  906. el.style.width = w + 'px';
  907. }
  908. if ((this._proxy && force) || !this._proxy) {
  909. if (this._wrap != this.get('element')) {
  910. this.get('element').style.width = w + 'px';
  911. }
  912. }
  913. }
  914. }
  915. if (anim) {
  916. if (YAHOO.util.Anim) {
  917. var _anim = new YAHOO.util.Anim(el, {
  918. height: {
  919. to: this._cache.height
  920. },
  921. width: {
  922. to: this._cache.width
  923. }
  924. }, this.get('animateDuration'), this.get('animateEasing'));
  925. if (this._positioned) {
  926. if (t) {
  927. _anim.attributes.top = {
  928. to: parseInt(t, 10)
  929. };
  930. }
  931. if (l) {
  932. _anim.attributes.left = {
  933. to: parseInt(l, 10)
  934. };
  935. }
  936. }
  937. if (this._wrap != this.get('element')) {
  938. _anim.onTween.subscribe(function() {
  939. this.get('element').style.height = el.style.height;
  940. this.get('element').style.width = el.style.width;
  941. }, this, true);
  942. }
  943. _anim.onComplete.subscribe(function() {
  944. YAHOO.log('Animation onComplete fired', 'info', 'Resize');
  945. this.set('height', h);
  946. this.set('width', w);
  947. this.fireEvent('resize', { ev: 'resize', target: this, height: h, width: w, top: t, left: l });
  948. }, this, true);
  949. _anim.animate();
  950. }
  951. } else {
  952. if (this._proxy && !force) {
  953. YAHOO.log('proxyResize', 'info', 'Resize');
  954. this.fireEvent('proxyResize', { ev: 'proxyresize', target: this, height: h, width: w, top: t, left: l });
  955. } else {
  956. YAHOO.log('resize', 'info', 'Resize');
  957. this.fireEvent('resize', { ev: 'resize', target: this, height: h, width: w, top: t, left: l });
  958. }
  959. }
  960. return this;
  961. },
  962. /**
  963. * @private
  964. * @method _handle_for_br
  965. * @param {Object} args The arguments from the CustomEvent.
  966. * @description Handles the sizes for the Bottom Right handle.
  967. */
  968. _handle_for_br: function(args) {
  969. YAHOO.log('Handle BR', 'info', 'Resize');
  970. var newW = this._setWidth(args.e);
  971. var newH = this._setHeight(args.e);
  972. this.resize(args.e, newH, newW, 0, 0);
  973. },
  974. /**
  975. * @private
  976. * @method _handle_for_bl
  977. * @param {Object} args The arguments from the CustomEvent.
  978. * @description Handles the sizes for the Bottom Left handle.
  979. */
  980. _handle_for_bl: function(args) {
  981. YAHOO.log('Handle BL', 'info', 'Resize');
  982. var newW = this._setWidth(args.e, true);
  983. var newH = this._setHeight(args.e);
  984. var l = (newW - this._cache.width);
  985. this.resize(args.e, newH, newW, 0, l);
  986. },
  987. /**
  988. * @private
  989. * @method _handle_for_tl
  990. * @param {Object} args The arguments from the CustomEvent.
  991. * @description Handles the sizes for the Top Left handle.
  992. */
  993. _handle_for_tl: function(args) {
  994. YAHOO.log('Handle TL', 'info', 'Resize');
  995. var newW = this._setWidth(args.e, true);
  996. var newH = this._setHeight(args.e, true);
  997. var t = (newH - this._cache.height);
  998. var l = (newW - this._cache.width);
  999. this.resize(args.e, newH, newW, t, l);
  1000. },
  1001. /**
  1002. * @private
  1003. * @method _handle_for_tr
  1004. * @param {Object} args The arguments from the CustomEvent.
  1005. * @description Handles the sizes for the Top Right handle.
  1006. */
  1007. _handle_for_tr: function(args) {
  1008. YAHOO.log('Handle TR', 'info', 'Resize');
  1009. var newW = this._setWidth(args.e);
  1010. var newH = this._setHeight(args.e, true);
  1011. var t = (newH - this._cache.height);
  1012. this.resize(args.e, newH, newW, t, 0);
  1013. },
  1014. /**
  1015. * @private
  1016. * @method _handle_for_r
  1017. * @param {Object} args The arguments from the CustomEvent.
  1018. * @description Handles the sizes for the Right handle.
  1019. */
  1020. _handle_for_r: function(args) {
  1021. YAHOO.log('Handle R', 'info', 'Resize');
  1022. this._dds.r.setYConstraint(0,0);
  1023. var newW = this._setWidth(args.e);
  1024. this.resize(args.e, 0, newW, 0, 0);
  1025. },
  1026. /**
  1027. * @private
  1028. * @method _handle_for_l
  1029. * @param {Object} args The arguments from the CustomEvent.
  1030. * @description Handles the sizes for the Left handle.
  1031. */
  1032. _handle_for_l: function(args) {
  1033. YAHOO.log('Handle L', 'info', 'Resize');
  1034. this._dds.l.setYConstraint(0,0);
  1035. var newW = this._setWidth(args.e, true);
  1036. var l = (newW - this._cache.width);
  1037. this.resize(args.e, 0, newW, 0, l);
  1038. },
  1039. /**
  1040. * @private
  1041. * @method _handle_for_b
  1042. * @param {Object} args The arguments from the CustomEvent.
  1043. * @description Handles the sizes for the Bottom handle.
  1044. */
  1045. _handle_for_b: function(args) {
  1046. YAHOO.log('Handle B', 'info', 'Resize');
  1047. this._dds.b.setXConstraint(0,0);
  1048. var newH = this._setHeight(args.e);
  1049. this.resize(args.e, newH, 0, 0, 0);
  1050. },
  1051. /**
  1052. * @private
  1053. * @method _handle_for_t
  1054. * @param {Object} args The arguments from the CustomEvent.
  1055. * @description Handles the sizes for the Top handle.
  1056. */
  1057. _handle_for_t: function(args) {
  1058. YAHOO.log('Handle T', 'info', 'Resize');
  1059. this._dds.t.setXConstraint(0,0);
  1060. var newH = this._setHeight(args.e, true);
  1061. var t = (newH - this._cache.height);
  1062. this.resize(args.e, newH, 0, t, 0);
  1063. },
  1064. /**
  1065. * @private
  1066. * @method _setWidth
  1067. * @param {Event} ev The mouse event.
  1068. * @param {Boolean} flip Argument to determine the direction of the movement.
  1069. * @description Calculates the width based on the mouse event.
  1070. * @return {Number} The new value
  1071. */
  1072. _setWidth: function(ev, flip) {
  1073. YAHOO.log('Set width based on Event', 'info', 'Resize');
  1074. var xy = this._cache.xy[0],
  1075. w = this._cache.width,
  1076. x = Event.getPageX(ev),
  1077. nw = (x - xy);
  1078. if (flip) {
  1079. nw = (xy - x) + parseInt(this.get('width'), 10);
  1080. }
  1081. nw = this._snapTick(nw, this.get('xTicks'));
  1082. nw = this._checkWidth(nw);
  1083. return nw;
  1084. },
  1085. /**
  1086. * @private
  1087. * @method _checkWidth
  1088. * @param {Number} w The width to check.
  1089. * @description Checks the value passed against the maxWidth and minWidth.
  1090. * @return {Number} the new value
  1091. */
  1092. _checkWidth: function(w) {
  1093. YAHOO.log('Checking the min/max width', 'info', 'Resize');
  1094. if (this.get('minWidth')) {
  1095. if (w <= this.get('minWidth')) {
  1096. YAHOO.log('Using minWidth', 'info', 'Resize');
  1097. w = this.get('minWidth');
  1098. }
  1099. }
  1100. if (this.get('maxWidth')) {
  1101. if (w >= this.get('maxWidth')) {
  1102. YAHOO.log('Using Max Width', 'info', 'Resize');
  1103. w = this.get('maxWidth');
  1104. }
  1105. }
  1106. return w;
  1107. },
  1108. /**
  1109. * @private
  1110. * @method _checkHeight
  1111. * @param {Number} h The height to check.
  1112. * @description Checks the value passed against the maxHeight and minHeight.
  1113. * @return {Number} The new value
  1114. */
  1115. _checkHeight: function(h) {
  1116. YAHOO.log('Checking the min/max height', 'info', 'Resize');
  1117. if (this.get('minHeight')) {
  1118. if (h <= this.get('minHeight')) {
  1119. YAHOO.log('Using minHeight', 'info', 'Resize');
  1120. h = this.get('minHeight');
  1121. }
  1122. }
  1123. if (this.get('maxHeight')) {
  1124. if (h >= this.get('maxHeight')) {
  1125. YAHOO.log('using maxHeight', 'info', 'Resize');
  1126. h = this.get('maxHeight');
  1127. }
  1128. }
  1129. return h;
  1130. },
  1131. /**
  1132. * @private
  1133. * @method _setHeight
  1134. * @param {Event} ev The mouse event.
  1135. * @param {Boolean} flip Argument to determine the direction of the movement.
  1136. * @description Calculated the height based on the mouse event.
  1137. * @return {Number} The new value
  1138. */
  1139. _setHeight: function(ev, flip) {
  1140. YAHOO.log('Setting the height based on the Event', 'info', 'Resize');
  1141. var xy = this._cache.xy[1],
  1142. h = this._cache.height,
  1143. y = Event.getPageY(ev),
  1144. nh = (y - xy);
  1145. if (flip) {
  1146. nh = (xy - y) + parseInt(this.get('height'), 10);
  1147. }
  1148. nh = this._snapTick(nh, this.get('yTicks'));
  1149. nh = this._checkHeight(nh);
  1150. return nh;
  1151. },
  1152. /**
  1153. * @private
  1154. * @method _snapTick
  1155. * @param {Number} size The size to tick against.
  1156. * @param {Number} pix The tick pixels.
  1157. * @description Adjusts the number based on the ticks used.
  1158. * @return {Number} the new snapped position
  1159. */
  1160. _snapTick: function(size, pix) {
  1161. YAHOO.log('Snapping to ticks', 'info', 'Resize');
  1162. if (!size || !pix) {
  1163. return size;
  1164. }
  1165. var _s = size;
  1166. var _x = size % pix;
  1167. if (_x > 0) {
  1168. if (_x > (pix / 2)) {
  1169. _s = size + (pix - _x);
  1170. } else {
  1171. _s = size - _x;
  1172. }
  1173. }
  1174. return _s;
  1175. },
  1176. /**
  1177. * @private
  1178. * @method init
  1179. * @description The Resize class's initialization method
  1180. */
  1181. init: function(p_oElement, p_oAttributes) {
  1182. YAHOO.log('init', 'info', 'Resize');
  1183. this._locked = false;
  1184. this._cache = {
  1185. xy: [],
  1186. height: 0,
  1187. width: 0,
  1188. top: 0,
  1189. left: 0,
  1190. offsetHeight: 0,
  1191. offsetWidth: 0,
  1192. start: {
  1193. height: 0,
  1194. width: 0,
  1195. top: 0,
  1196. left: 0
  1197. }
  1198. };
  1199. Resize.superclass.init.call(this, p_oElement, p_oAttributes);
  1200. this.set('setSize', this.get('setSize'));
  1201. if (p_oAttributes.height) {
  1202. this.set('height', parseInt(p_oAttributes.height, 10));
  1203. } else {
  1204. var h = this.getStyle('height');
  1205. if (h == 'auto') {
  1206. this.set('height', parseInt(this.get('element').offsetHeight, 10));
  1207. }
  1208. }
  1209. if (p_oAttributes.width) {
  1210. this.set('width', parseInt(p_oAttributes.width, 10));
  1211. } else {
  1212. var w = this.getStyle('width');
  1213. if (w == 'auto') {
  1214. this.set('width', parseInt(this.get('element').offsetWidth, 10));
  1215. }
  1216. }
  1217. var id = p_oElement;
  1218. if (!Lang.isString(id)) {
  1219. id = D.generateId(id);
  1220. }