| // Copyright (c) 2005 Thomas Fakes (http://craz8.com) |
| // |
| // This code is substantially based on code from script.aculo.us which has the |
| // following copyright and permission notice |
| // |
| // Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) |
| // |
| // Permission is hereby granted, free of charge, to any person obtaining |
| // a copy of this software and associated documentation files (the |
| // "Software"), to deal in the Software without restriction, including |
| // without limitation the rights to use, copy, modify, merge, publish, |
| // distribute, sublicense, and/or sell copies of the Software, and to |
| // permit persons to whom the Software is furnished to do so, subject to |
| // the following conditions: |
| // |
| // The above copyright notice and this permission notice shall be |
| // included in all copies or substantial portions of the Software. |
| // |
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
| // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
| // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
| // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE |
| // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION |
| // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION |
| // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
| |
| var Resizeable = Class.create(); |
| Resizeable.prototype = { |
| initialize: function(element) { |
| var options = Object.extend({ |
| top: 6, |
| bottom: 6, |
| left: 6, |
| right: 6, |
| minHeight: 0, |
| minWidth: 0, |
| zindex: 1000, |
| resize: null, |
| duringresize: null |
| }, arguments[1] || {}); |
| |
| this.element = $(element); |
| this.handle = this.element; |
| |
| Element.makePositioned(this.element); // fix IE |
| |
| this.options = options; |
| |
| this.active = false; |
| this.resizing = false; |
| this.currentDirection = ''; |
| |
| this.eventMouseDown = this.startResize.bindAsEventListener(this); |
| this.eventMouseUp = this.endResize.bindAsEventListener(this); |
| this.eventMouseMove = this.update.bindAsEventListener(this); |
| this.eventCursorCheck = this.cursor.bindAsEventListener(this); |
| this.eventKeypress = this.keyPress.bindAsEventListener(this); |
| |
| this.registerEvents(); |
| }, |
| destroy: function() { |
| Event.stopObserving(this.handle, "mousedown", this.eventMouseDown); |
| this.unregisterEvents(); |
| }, |
| registerEvents: function() { |
| Event.observe(document, "mouseup", this.eventMouseUp); |
| Event.observe(document, "mousemove", this.eventMouseMove); |
| Event.observe(document, "keypress", this.eventKeypress); |
| Event.observe(this.handle, "mousedown", this.eventMouseDown); |
| Event.observe(this.element, "mousemove", this.eventCursorCheck); |
| }, |
| unregisterEvents: function() { |
| //if(!this.active) return; |
| //Event.stopObserving(document, "mouseup", this.eventMouseUp); |
| //Event.stopObserving(document, "mousemove", this.eventMouseMove); |
| //Event.stopObserving(document, "mousemove", this.eventCursorCheck); |
| //Event.stopObserving(document, "keypress", this.eventKeypress); |
| }, |
| startResize: function(event) { |
| if(Event.isLeftClick(event)) { |
| |
| // abort on form elements, fixes a Firefox issue |
| var src = Event.element(event); |
| if(src.tagName && ( |
| src.tagName=='INPUT' || |
| src.tagName=='SELECT' || |
| src.tagName=='BUTTON' || |
| src.tagName=='TEXTAREA')) return; |
| |
| var dir = this.directions(event); |
| if (dir.length > 0) { |
| this.active = true; |
| var offsets = Position.cumulativeOffset(this.element); |
| this.startTop = offsets[1]; |
| this.startLeft = offsets[0]; |
| this.startWidth = parseInt(Element.getStyle(this.element, 'width')); |
| this.startHeight = parseInt(Element.getStyle(this.element, 'height')); |
| this.startX = event.clientX + document.body.scrollLeft + document.documentElement.scrollLeft; |
| this.startY = event.clientY + document.body.scrollTop + document.documentElement.scrollTop; |
| |
| this.currentDirection = dir; |
| Event.stop(event); |
| } |
| } |
| }, |
| finishResize: function(event, success) { |
| // this.unregisterEvents(); |
| |
| this.active = false; |
| this.resizing = false; |
| |
| if(this.options.zindex) |
| this.element.style.zIndex = this.originalZ; |
| |
| if (this.options.resize) { |
| this.options.resize(this.element); |
| } |
| }, |
| keyPress: function(event) { |
| if(this.active) { |
| if(event.keyCode==Event.KEY_ESC) { |
| this.finishResize(event, false); |
| Event.stop(event); |
| } |
| } |
| }, |
| endResize: function(event) { |
| if(this.active && this.resizing) { |
| this.finishResize(event, true); |
| Event.stop(event); |
| } |
| this.active = false; |
| this.resizing = false; |
| }, |
| draw: function(event) { |
| var pointer = [Event.pointerX(event), Event.pointerY(event)]; |
| var style = this.element.style; |
| if (this.currentDirection.indexOf('n') != -1) { |
| var pointerMoved = this.startY - pointer[1]; |
| var margin = Element.getStyle(this.element, 'margin-top') || "0"; |
| var newHeight = this.startHeight + pointerMoved; |
| if (newHeight > this.options.minHeight) { |
| style.height = newHeight + "px"; |
| style.top = (this.startTop - pointerMoved - parseInt(margin)) + "px"; |
| } |
| } |
| if (this.currentDirection.indexOf('w') != -1) { |
| var pointerMoved = this.startX - pointer[0]; |
| var margin = Element.getStyle(this.element, 'margin-left') || "0"; |
| var newWidth = this.startWidth + pointerMoved; |
| if (newWidth > this.options.minWidth) { |
| style.left = (this.startLeft - pointerMoved - parseInt(margin)) + "px"; |
| style.width = newWidth + "px"; |
| } |
| } |
| if (this.currentDirection.indexOf('s') != -1) { |
| var newHeight = this.startHeight + pointer[1] - this.startY; |
| if (newHeight > this.options.minHeight) { |
| style.height = newHeight + "px"; |
| } |
| } |
| if (this.currentDirection.indexOf('e') != -1) { |
| var newWidth = this.startWidth + pointer[0] - this.startX; |
| if (newWidth > this.options.minWidth) { |
| style.width = newWidth + "px"; |
| } |
| } |
| if(style.visibility=="hidden") style.visibility = ""; // fix gecko rendering |
| }, |
| between: function(val, low, high) { |
| return (val >= low && val < high); |
| }, |
| directions: function(event) { |
| var pointer = [Event.pointerX(event), Event.pointerY(event)]; |
| var offsets = Position.cumulativeOffset(this.element); |
| |
| var cursor = ''; |
| if (this.between(pointer[1] - offsets[1], 0, this.options.top)) cursor += 'n'; |
| if (this.between((offsets[1] + this.element.offsetHeight) - pointer[1], 0, this.options.bottom)) cursor += 's'; |
| if (this.between(pointer[0] - offsets[0], 0, this.options.left)) cursor += 'w'; |
| if (this.between((offsets[0] + this.element.offsetWidth) - pointer[0], 0, this.options.right)) cursor += 'e'; |
| |
| return cursor; |
| }, |
| cursor: function(event) { |
| var cursor = this.directions(event); |
| if (cursor.length > 0) { |
| cursor += '-resize'; |
| } else { |
| cursor = ''; |
| } |
| this.element.style.cursor = cursor; |
| }, |
| update: function(event) { |
| if(this.active) { |
| if(!this.resizing) { |
| var style = this.element.style; |
| this.resizing = true; |
| |
| if(Element.getStyle(this.element,'position')=='') |
| style.position = "relative"; |
| |
| if(this.options.zindex) { |
| this.originalZ = parseInt(Element.getStyle(this.element,'z-index') || 0); |
| style.zIndex = this.options.zindex; |
| } |
| } |
| this.draw(event); |
| if(this.options.duringresize) { this.options.duringresize(this.element); } |
| // fix AppleWebKit rendering |
| if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0); |
| Event.stop(event); |
| return false; |
| } |
| } |
| } |