initial import from onelab svn codebase
[plewww.git] / misc / textarea.js
1 // $Id: textarea.js 144 2007-03-28 07:52:20Z thierry $
2
3 if (isJsEnabled()) {
4   addLoadEvent(textAreaAutoAttach);
5 }
6
7 function textAreaAutoAttach(event, parent) {
8   if (typeof parent == 'undefined') {
9     // Attach to all visible textareas.
10     textareas = document.getElementsByTagName('textarea');
11   }
12   else {
13     // Attach to all visible textareas inside parent.
14     textareas = parent.getElementsByTagName('textarea');
15   }
16   var textarea;
17   for (var i = 0; textarea = textareas[i]; ++i) {
18     if (hasClass(textarea, 'resizable') && !hasClass(textarea.nextSibling, 'grippie')) {
19       if (typeof dimensions(textarea).width != 'undefined' && dimensions(textarea).width != 0) {
20         new textArea(textarea);
21       }
22     }
23   }
24 }
25
26 function textArea(element) {
27   var ta = this;
28   this.element = element;
29   this.parent = this.element.parentNode;
30   this.dimensions = dimensions(element);
31
32   // Prepare wrapper
33   this.wrapper = document.createElement('div');
34   this.wrapper.className = 'resizable-textarea';
35   this.parent.insertBefore(this.wrapper, this.element);
36
37   // Add grippie and measure it
38   this.grippie = document.createElement('div');
39   this.grippie.className = 'grippie';
40   this.wrapper.appendChild(this.grippie);
41   this.grippie.dimensions = dimensions(this.grippie);
42   this.grippie.onmousedown = function (e) { ta.beginDrag(e); };
43
44   // Set wrapper and textarea dimensions
45   this.wrapper.style.height = this.dimensions.height + this.grippie.dimensions.height + 1 +'px';
46   this.element.style.marginBottom = '0px';
47   this.element.style.width = '100%';
48   this.element.style.height = this.dimensions.height +'px';
49
50   // Wrap textarea
51   removeNode(this.element);
52   this.wrapper.insertBefore(this.element, this.grippie);
53
54   // Measure difference between desired and actual textarea dimensions to account for padding/borders
55   this.widthOffset = dimensions(this.wrapper).width - this.dimensions.width;
56
57   // Make the grippie line up in various browsers
58   if (window.opera) {
59     // Opera
60     this.grippie.style.marginRight = '4px';
61   }
62   if (document.all && !window.opera) {
63     // IE
64     this.grippie.style.width = '100%';
65     this.grippie.style.paddingLeft = '2px';
66   }
67   // Mozilla
68   this.element.style.MozBoxSizing = 'border-box';
69
70   this.heightOffset = absolutePosition(this.grippie).y - absolutePosition(this.element).y - this.dimensions.height;
71 }
72
73 textArea.prototype.beginDrag = function (event) {
74   if (document.isDragging) {
75     return;
76   }
77   document.isDragging = true;
78
79   event = event || window.event;
80   // Capture mouse
81   var cp = this;
82   this.oldMoveHandler = document.onmousemove;
83   document.onmousemove = function(e) { cp.handleDrag(e); };
84   this.oldUpHandler = document.onmouseup;
85   document.onmouseup = function(e) { cp.endDrag(e); };
86
87   // Store drag offset from grippie top
88   var pos = absolutePosition(this.grippie);
89   this.dragOffset = event.clientY - pos.y;
90
91   // Make transparent
92   this.element.style.opacity = 0.5;
93
94   // Process
95   this.handleDrag(event);
96 }
97
98 textArea.prototype.handleDrag = function (event) {
99   event = event || window.event;
100   // Get coordinates relative to text area
101   var pos = absolutePosition(this.element);
102   var y = event.clientY - pos.y;
103
104   // Set new height
105   var height = Math.max(32, y - this.dragOffset - this.heightOffset);
106   this.wrapper.style.height = height + this.grippie.dimensions.height + 1 + 'px';
107   this.element.style.height = height + 'px';
108
109   // Avoid text selection
110   stopEvent(event);
111 }
112
113 textArea.prototype.endDrag = function (event) {
114   // Uncapture mouse
115   document.onmousemove = this.oldMoveHandler;
116   document.onmouseup = this.oldUpHandler;
117
118   // Restore opacity
119   this.element.style.opacity = 1.0;
120   document.isDragging = false;
121 }
122