]> git.wh0rd.org - 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 });