summaryrefslogtreecommitdiff
path: root/lib/dijit/form/_ExpandingTextAreaMixin.js.uncompressed.js
diff options
context:
space:
mode:
Diffstat (limited to 'lib/dijit/form/_ExpandingTextAreaMixin.js.uncompressed.js')
-rw-r--r--lib/dijit/form/_ExpandingTextAreaMixin.js.uncompressed.js130
1 files changed, 130 insertions, 0 deletions
diff --git a/lib/dijit/form/_ExpandingTextAreaMixin.js.uncompressed.js b/lib/dijit/form/_ExpandingTextAreaMixin.js.uncompressed.js
new file mode 100644
index 000000000..382663e98
--- /dev/null
+++ b/lib/dijit/form/_ExpandingTextAreaMixin.js.uncompressed.js
@@ -0,0 +1,130 @@
+define("dijit/form/_ExpandingTextAreaMixin", [
+ "dojo/_base/declare", // declare
+ "dojo/dom-construct", // domConstruct.create
+ "dojo/has",
+ "dojo/_base/lang", // lang.hitch
+ "dojo/on",
+ "dojo/_base/window", // win.body
+ "../Viewport"
+], function(declare, domConstruct, has, lang, on, win, Viewport){
+
+ // module:
+ // dijit/form/_ExpandingTextAreaMixin
+
+ // feature detection, true for mozilla and webkit
+ has.add("textarea-needs-help-shrinking", function(){
+ var body = win.body(), // note: if multiple documents exist, doesn't matter which one we use
+ te = domConstruct.create('textarea', {
+ rows:"5",
+ cols:"20",
+ value: ' ',
+ 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' }
+ }, body, "last");
+ var needsHelpShrinking = te.scrollHeight >= te.clientHeight;
+ body.removeChild(te);
+ return needsHelpShrinking;
+ });
+
+ return declare("dijit.form._ExpandingTextAreaMixin", null, {
+ // summary:
+ // Mixin for textarea widgets to add auto-expanding capability
+
+ _setValueAttr: function(){
+ this.inherited(arguments);
+ this.resize();
+ },
+
+ postCreate: function(){
+ this.inherited(arguments);
+ var textarea = this.textbox;
+ textarea.style.overflowY = "hidden";
+ this.own(on(textarea, "focus, resize", lang.hitch(this, "_resizeLater")));
+ },
+
+ startup: function(){
+ this.inherited(arguments);
+ this.own(Viewport.on("resize", lang.hitch(this, "_resizeLater")));
+ this._resizeLater();
+ },
+
+ _onInput: function(e){
+ this.inherited(arguments);
+ this.resize();
+ },
+
+ _estimateHeight: function(){
+ // summary:
+ // Approximate the height when the textarea is invisible with the number of lines in the text.
+ // Fails when someone calls setValue with a long wrapping line, but the layout fixes itself when the user clicks inside so . . .
+ // In IE, the resize event is supposed to fire when the textarea becomes visible again and that will correct the size automatically.
+ //
+ var textarea = this.textbox;
+ // #rows = #newlines+1
+ textarea.rows = (textarea.value.match(/\n/g) || []).length + 1;
+ },
+
+ _resizeLater: function(){
+ this.defer("resize");
+ },
+
+ resize: function(){
+ // summary:
+ // Resizes the textarea vertically (should be called after a style/value change)
+
+ var textarea = this.textbox;
+
+ function textareaScrollHeight(){
+ var empty = false;
+ if(textarea.value === ''){
+ textarea.value = ' ';
+ empty = true;
+ }
+ var sh = textarea.scrollHeight;
+ if(empty){ textarea.value = ''; }
+ return sh;
+ }
+
+ if(textarea.style.overflowY == "hidden"){ textarea.scrollTop = 0; }
+ if(this.busyResizing){ return; }
+ this.busyResizing = true;
+ if(textareaScrollHeight() || textarea.offsetHeight){
+ var newH = textareaScrollHeight() + Math.max(textarea.offsetHeight - textarea.clientHeight, 0);
+ var newHpx = newH + "px";
+ if(newHpx != textarea.style.height){
+ textarea.style.height = newHpx;
+ textarea.rows = 1; // rows can act like a minHeight if not cleared
+ }
+ if(has("textarea-needs-help-shrinking")){
+ var origScrollHeight = textareaScrollHeight(),
+ newScrollHeight = origScrollHeight,
+ origMinHeight = textarea.style.minHeight,
+ decrement = 4, // not too fast, not too slow
+ thisScrollHeight,
+ origScrollTop = textarea.scrollTop;
+ textarea.style.minHeight = newHpx; // maintain current height
+ textarea.style.height = "auto"; // allow scrollHeight to change
+ while(newH > 0){
+ textarea.style.minHeight = Math.max(newH - decrement, 4) + "px";
+ thisScrollHeight = textareaScrollHeight();
+ var change = newScrollHeight - thisScrollHeight;
+ newH -= change;
+ if(change < decrement){
+ break; // scrollHeight didn't shrink
+ }
+ newScrollHeight = thisScrollHeight;
+ decrement <<= 1;
+ }
+ textarea.style.height = newH + "px";
+ textarea.style.minHeight = origMinHeight;
+ textarea.scrollTop = origScrollTop;
+ }
+ textarea.style.overflowY = textareaScrollHeight() > textarea.clientHeight ? "auto" : "hidden";
+ if(textarea.style.overflowY == "hidden"){ textarea.scrollTop = 0; }
+ }else{
+ // hidden content of unknown size
+ this._estimateHeight();
+ }
+ this.busyResizing = false;
+ }
+ });
+});