1 // Copyright (c) 2005 Thomas Fakes (http://craz8.com)
\r
3 // This code is substantially based on code from script.aculo.us which has the
\r
4 // following copyright and permission notice
\r
6 // Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
\r
8 // Permission is hereby granted, free of charge, to any person obtaining
\r
9 // a copy of this software and associated documentation files (the
\r
10 // "Software"), to deal in the Software without restriction, including
\r
11 // without limitation the rights to use, copy, modify, merge, publish,
\r
12 // distribute, sublicense, and/or sell copies of the Software, and to
\r
13 // permit persons to whom the Software is furnished to do so, subject to
\r
14 // the following conditions:
\r
16 // The above copyright notice and this permission notice shall be
\r
17 // included in all copies or substantial portions of the Software.
\r
19 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
\r
20 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
\r
21 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
\r
22 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
\r
23 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
\r
24 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
\r
25 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\r
27 var Resizeable = Class.create();
\r
28 Resizeable.prototype = {
\r
29 initialize: function(element) {
\r
30 var options = Object.extend({
\r
39 }, arguments[1] || {});
\r
41 this.element = $(element);
\r
42 this.handle = this.element;
\r
44 Element.makePositioned(this.element); // fix IE
\r
46 this.options = options;
\r
48 this.active = false;
\r
49 this.resizing = false;
\r
50 this.currentDirection = '';
\r
52 this.eventMouseDown = this.startResize.bindAsEventListener(this);
\r
53 this.eventMouseUp = this.endResize.bindAsEventListener(this);
\r
54 this.eventMouseMove = this.update.bindAsEventListener(this);
\r
55 this.eventCursorCheck = this.cursor.bindAsEventListener(this);
\r
56 this.eventKeypress = this.keyPress.bindAsEventListener(this);
\r
58 this.registerEvents();
\r
60 destroy: function() {
\r
61 Event.stopObserving(this.handle, "mousedown", this.eventMouseDown);
\r
62 this.unregisterEvents();
\r
64 registerEvents: function() {
\r
65 Event.observe(document, "mouseup", this.eventMouseUp);
\r
66 Event.observe(document, "mousemove", this.eventMouseMove);
\r
67 Event.observe(document, "keypress", this.eventKeypress);
\r
68 Event.observe(this.handle, "mousedown", this.eventMouseDown);
\r
69 Event.observe(this.element, "mousemove", this.eventCursorCheck);
\r
71 unregisterEvents: function() {
\r
72 //if(!this.active) return;
\r
73 //Event.stopObserving(document, "mouseup", this.eventMouseUp);
\r
74 //Event.stopObserving(document, "mousemove", this.eventMouseMove);
\r
75 //Event.stopObserving(document, "mousemove", this.eventCursorCheck);
\r
76 //Event.stopObserving(document, "keypress", this.eventKeypress);
\r
78 startResize: function(event) {
\r
79 if(Event.isLeftClick(event)) {
\r
81 // abort on form elements, fixes a Firefox issue
\r
82 var src = Event.element(event);
\r
84 src.tagName=='INPUT' ||
\r
85 src.tagName=='SELECT' ||
\r
86 src.tagName=='BUTTON' ||
\r
87 src.tagName=='TEXTAREA')) return;
\r
89 var dir = this.directions(event);
\r
90 if (dir.length > 0) {
\r
92 var offsets = Position.cumulativeOffset(this.element);
\r
93 this.startTop = offsets[1];
\r
94 this.startLeft = offsets[0];
\r
95 this.startWidth = parseInt(Element.getStyle(this.element, 'width'));
\r
96 this.startHeight = parseInt(Element.getStyle(this.element, 'height'));
\r
97 this.startX = event.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
\r
98 this.startY = event.clientY + document.body.scrollTop + document.documentElement.scrollTop;
\r
100 this.currentDirection = dir;
\r
105 finishResize: function(event, success) {
\r
106 // this.unregisterEvents();
\r
108 this.active = false;
\r
109 this.resizing = false;
\r
111 if(this.options.zindex)
\r
112 this.element.style.zIndex = this.originalZ;
\r
114 if (this.options.resize) {
\r
115 this.options.resize(this.element);
\r
118 keyPress: function(event) {
\r
120 if(event.keyCode==Event.KEY_ESC) {
\r
121 this.finishResize(event, false);
\r
126 endResize: function(event) {
\r
127 if(this.active && this.resizing) {
\r
128 this.finishResize(event, true);
\r
131 this.active = false;
\r
132 this.resizing = false;
\r
134 draw: function(event) {
\r
135 var pointer = [Event.pointerX(event), Event.pointerY(event)];
\r
136 var style = this.element.style;
\r
137 if (this.currentDirection.indexOf('n') != -1) {
\r
138 var pointerMoved = this.startY - pointer[1];
\r
139 var margin = Element.getStyle(this.element, 'margin-top') || "0";
\r
140 var newHeight = this.startHeight + pointerMoved;
\r
141 if (newHeight > this.options.minHeight) {
\r
142 style.height = newHeight + "px";
\r
143 style.top = (this.startTop - pointerMoved - parseInt(margin)) + "px";
\r
146 if (this.currentDirection.indexOf('w') != -1) {
\r
147 var pointerMoved = this.startX - pointer[0];
\r
148 var margin = Element.getStyle(this.element, 'margin-left') || "0";
\r
149 var newWidth = this.startWidth + pointerMoved;
\r
150 if (newWidth > this.options.minWidth) {
\r
151 style.left = (this.startLeft - pointerMoved - parseInt(margin)) + "px";
\r
152 style.width = newWidth + "px";
\r
155 if (this.currentDirection.indexOf('s') != -1) {
\r
156 var newHeight = this.startHeight + pointer[1] - this.startY;
\r
157 if (newHeight > this.options.minHeight) {
\r
158 style.height = newHeight + "px";
\r
161 if (this.currentDirection.indexOf('e') != -1) {
\r
162 var newWidth = this.startWidth + pointer[0] - this.startX;
\r
163 if (newWidth > this.options.minWidth) {
\r
164 style.width = newWidth + "px";
\r
167 if(style.visibility=="hidden") style.visibility = ""; // fix gecko rendering
\r
169 between: function(val, low, high) {
\r
170 return (val >= low && val < high);
\r
172 directions: function(event) {
\r
173 var pointer = [Event.pointerX(event), Event.pointerY(event)];
\r
174 var offsets = Position.cumulativeOffset(this.element);
\r
177 if (this.between(pointer[1] - offsets[1], 0, this.options.top)) cursor += 'n';
\r
178 if (this.between((offsets[1] + this.element.offsetHeight) - pointer[1], 0, this.options.bottom)) cursor += 's';
\r
179 if (this.between(pointer[0] - offsets[0], 0, this.options.left)) cursor += 'w';
\r
180 if (this.between((offsets[0] + this.element.offsetWidth) - pointer[0], 0, this.options.right)) cursor += 'e';
\r
184 cursor: function(event) {
\r
185 var cursor = this.directions(event);
\r
186 if (cursor.length > 0) {
\r
187 cursor += '-resize';
\r
191 this.element.style.cursor = cursor;
\r
193 update: function(event) {
\r
195 if(!this.resizing) {
\r
196 var style = this.element.style;
\r
197 this.resizing = true;
\r
199 if(Element.getStyle(this.element,'position')=='')
\r
200 style.position = "relative";
\r
202 if(this.options.zindex) {
\r
203 this.originalZ = parseInt(Element.getStyle(this.element,'z-index') || 0);
\r
204 style.zIndex = this.options.zindex;
\r
209 // fix AppleWebKit rendering
\r
210 if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0);
\r