]> git.wh0rd.org - tt-rss.git/blob - lib/dijit/form/_ExpandingTextAreaMixin.js.uncompressed.js
upgrade dojo to 1.8.3 (refs #570)
[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/has",
5 "dojo/_base/lang", // lang.hitch
6 "dojo/on",
7 "dojo/_base/window", // win.body
8 "../Viewport"
9 ], function(declare, domConstruct, has, lang, on, win, Viewport){
10
11 // module:
12 // dijit/form/_ExpandingTextAreaMixin
13
14 // feature detection, true for mozilla and webkit
15 has.add("textarea-needs-help-shrinking", function(){
16 var body = win.body(), // note: if multiple documents exist, doesn't matter which one we use
17 te = domConstruct.create('textarea', {
18 rows:"5",
19 cols:"20",
20 value: ' ',
21 style: {zoom:1, fontSize:"12px", height:"96px", overflow:'hidden', visibility:'hidden', position:'absolute', border:"5px solid white", margin:"0", padding:"0", boxSizing: 'border-box', MsBoxSizing: 'border-box', WebkitBoxSizing: 'border-box', MozBoxSizing: 'border-box' }
22 }, body, "last");
23 var needsHelpShrinking = te.scrollHeight >= te.clientHeight;
24 body.removeChild(te);
25 return needsHelpShrinking;
26 });
27
28 return declare("dijit.form._ExpandingTextAreaMixin", null, {
29 // summary:
30 // Mixin for textarea widgets to add auto-expanding capability
31
32 _setValueAttr: function(){
33 this.inherited(arguments);
34 this.resize();
35 },
36
37 postCreate: function(){
38 this.inherited(arguments);
39 var textarea = this.textbox;
40 textarea.style.overflowY = "hidden";
41 this.own(on(textarea, "focus, resize", lang.hitch(this, "_resizeLater")));
42 },
43
44 startup: function(){
45 this.inherited(arguments);
46 this.own(Viewport.on("resize", lang.hitch(this, "_resizeLater")));
47 this._resizeLater();
48 },
49
50 _onInput: function(e){
51 this.inherited(arguments);
52 this.resize();
53 },
54
55 _estimateHeight: function(){
56 // summary:
57 // Approximate the height when the textarea is invisible with the number of lines in the text.
58 // Fails when someone calls setValue with a long wrapping line, but the layout fixes itself when the user clicks inside so . . .
59 // In IE, the resize event is supposed to fire when the textarea becomes visible again and that will correct the size automatically.
60 //
61 var textarea = this.textbox;
62 // #rows = #newlines+1
63 textarea.rows = (textarea.value.match(/\n/g) || []).length + 1;
64 },
65
66 _resizeLater: function(){
67 this.defer("resize");
68 },
69
70 resize: function(){
71 // summary:
72 // Resizes the textarea vertically (should be called after a style/value change)
73
74 var textarea = this.textbox;
75
76 function textareaScrollHeight(){
77 var empty = false;
78 if(textarea.value === ''){
79 textarea.value = ' ';
80 empty = true;
81 }
82 var sh = textarea.scrollHeight;
83 if(empty){ textarea.value = ''; }
84 return sh;
85 }
86
87 if(textarea.style.overflowY == "hidden"){ textarea.scrollTop = 0; }
88 if(this.busyResizing){ return; }
89 this.busyResizing = true;
90 if(textareaScrollHeight() || textarea.offsetHeight){
91 var newH = textareaScrollHeight() + Math.max(textarea.offsetHeight - textarea.clientHeight, 0);
92 var newHpx = newH + "px";
93 if(newHpx != textarea.style.height){
94 textarea.style.height = newHpx;
95 textarea.rows = 1; // rows can act like a minHeight if not cleared
96 }
97 if(has("textarea-needs-help-shrinking")){
98 var origScrollHeight = textareaScrollHeight(),
99 newScrollHeight = origScrollHeight,
100 origMinHeight = textarea.style.minHeight,
101 decrement = 4, // not too fast, not too slow
102 thisScrollHeight,
103 origScrollTop = textarea.scrollTop;
104 textarea.style.minHeight = newHpx; // maintain current height
105 textarea.style.height = "auto"; // allow scrollHeight to change
106 while(newH > 0){
107 textarea.style.minHeight = Math.max(newH - decrement, 4) + "px";
108 thisScrollHeight = textareaScrollHeight();
109 var change = newScrollHeight - thisScrollHeight;
110 newH -= change;
111 if(change < decrement){
112 break; // scrollHeight didn't shrink
113 }
114 newScrollHeight = thisScrollHeight;
115 decrement <<= 1;
116 }
117 textarea.style.height = newH + "px";
118 textarea.style.minHeight = origMinHeight;
119 textarea.scrollTop = origScrollTop;
120 }
121 textarea.style.overflowY = textareaScrollHeight() > textarea.clientHeight ? "auto" : "hidden";
122 if(textarea.style.overflowY == "hidden"){ textarea.scrollTop = 0; }
123 }else{
124 // hidden content of unknown size
125 this._estimateHeight();
126 }
127 this.busyResizing = false;
128 }
129 });
130 });