]> git.wh0rd.org Git - tt-rss.git/blob - lib/dijit/form/_ExpandingTextAreaMixin.js.uncompressed.js
update dojo to 1.7.3
[tt-rss.git] / lib / dijit / form / _ExpandingTextAreaMixin.js.uncompressed.js
1 define("dijit/form/_ExpandingTextAreaMixin", [
2         "dojo/_base/declare", // declare
3         "dojo/dom-construct", // domConstruct.create
4         "dojo/_base/lang", // lang.hitch
5         "dojo/_base/window" // win.body
6 ], function(declare, domConstruct, lang, win){
7
8         // module:
9         //              dijit/form/_ExpandingTextAreaMixin
10         // summary:
11         //              Mixin for textarea widgets to add auto-expanding capability
12
13         // feature detection
14         var needsHelpShrinking;
15
16         return declare("dijit.form._ExpandingTextAreaMixin", null, {
17                 // summary:
18                 //              Mixin for textarea widgets to add auto-expanding capability
19
20                 _setValueAttr: function(){
21                         this.inherited(arguments);
22                         this.resize();
23                 },
24
25                 postCreate: function(){
26                         this.inherited(arguments);
27                         var textarea = this.textbox;
28
29                         if(needsHelpShrinking == undefined){
30                                 var te = domConstruct.create('textarea', {rows:"5", cols:"20", value: ' ', style: {zoom:1, overflow:'hidden', visibility:'hidden', position:'absolute', border:"0px solid black", padding:"0px"}}, win.body(), "last");
31                                 needsHelpShrinking = te.scrollHeight >= te.clientHeight;
32                                 win.body().removeChild(te);
33                         }
34                         this.connect(textarea, "onscroll", "_resizeLater");
35                         this.connect(textarea, "onresize", "_resizeLater");
36                         this.connect(textarea, "onfocus", "_resizeLater");
37                         textarea.style.overflowY = "hidden";
38                         this._estimateHeight();
39                         this._resizeLater();
40                 },
41
42                 _onInput: function(e){
43                         this.inherited(arguments);
44                         this.resize();
45                 },
46
47                 _estimateHeight: function(){
48                         // summary:
49                         //              Approximate the height when the textarea is invisible with the number of lines in the text.
50                         //              Fails when someone calls setValue with a long wrapping line, but the layout fixes itself when the user clicks inside so . . .
51                         //              In IE, the resize event is supposed to fire when the textarea becomes visible again and that will correct the size automatically.
52                         //
53                         var textarea = this.textbox;
54                         textarea.style.height = "auto";
55                         // #rows = #newlines+1
56                         // Note: on Moz, the following #rows appears to be 1 too many.
57                         // Actually, Moz is reserving room for the scrollbar.
58                         // If you increase the font size, this behavior becomes readily apparent as the last line gets cut off without the +1.
59                         textarea.rows = (textarea.value.match(/\n/g) || []).length + 2;
60                 },
61
62                 _resizeLater: function(){
63                         this.defer("resize");
64                 },
65
66                 resize: function(){
67                         // summary:
68                         //              Resizes the textarea vertically (should be called after a style/value change)
69                         function textareaScrollHeight(){
70                                 var empty = false;
71                                 if(textarea.value === ''){
72                                         textarea.value = ' ';
73                                         empty = true;
74                                 }
75                                 var sh = textarea.scrollHeight;
76                                 if(empty){ textarea.value = ''; }
77                                 return sh;
78                         }
79
80                         var textarea = this.textbox;
81                         if(textarea.style.overflowY == "hidden"){ textarea.scrollTop = 0; }
82                         if(this.busyResizing){ return; }
83                         this.busyResizing = true;
84                         if(textareaScrollHeight() || textarea.offsetHeight){
85                                 var currentHeight = textarea.style.height;
86                                 if(!(/px/.test(currentHeight))){
87                                         currentHeight = textareaScrollHeight();
88                                         textarea.rows = 1;
89                                         textarea.style.height = currentHeight + "px";
90                                 }
91                                 var newH = Math.max(Math.max(textarea.offsetHeight, parseInt(currentHeight)) - textarea.clientHeight, 0) + textareaScrollHeight();
92                                 var newHpx = newH + "px";
93                                 if(newHpx != textarea.style.height){
94                                         textarea.rows = 1;
95                                         textarea.style.height = newHpx;
96                                 }
97                                 if(needsHelpShrinking){
98                                         var     origScrollHeight = textareaScrollHeight(),
99                                                 newScrollHeight = origScrollHeight,
100                                                 origMinHeight = textarea.style.minHeight,
101                                                 decrement = 4, // not too fast, not too slow
102                                                 thisScrollHeight;
103                                         textarea.style.minHeight = newHpx; // maintain current height
104                                         textarea.style.height = "auto"; // allow scrollHeight to change
105                                         while(newH > 0){
106                                                 textarea.style.minHeight = Math.max(newH - decrement, 4) + "px";
107                                                 thisScrollHeight = textareaScrollHeight();
108                                                 var change = newScrollHeight - thisScrollHeight;
109                                                 newH -= change;
110                                                 if(change < decrement){
111                                                         break; // scrollHeight didn't shrink
112                                                 }
113                                                 newScrollHeight = thisScrollHeight;
114                                                 decrement <<= 1;
115                                         }
116                                         textarea.style.height = newH + "px";
117                                         textarea.style.minHeight = origMinHeight;
118                                 }
119                                 textarea.style.overflowY = textareaScrollHeight() > textarea.clientHeight ? "auto" : "hidden";
120                         }else{
121                                 // hidden content of unknown size
122                                 this._estimateHeight();
123                         }
124                         this.busyResizing = false;
125                 }
126         });
127 });