]> git.pond.sub.org Git - eow/blob - static/dojo-release-1.1.1/dijit/form/Textarea.js
Comment class stub
[eow] / static / dojo-release-1.1.1 / dijit / form / Textarea.js
1 if(!dojo._hasResource["dijit.form.Textarea"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
2 dojo._hasResource["dijit.form.Textarea"] = true;
3 dojo.provide("dijit.form.Textarea");
4
5 dojo.require("dijit.form._FormWidget");
6 dojo.require("dojo.i18n");
7 dojo.requireLocalization("dijit.form", "Textarea", null, "zh,pt,da,tr,ru,de,ROOT,sv,ja,he,fi,nb,el,ar,pt-pt,cs,fr,es,ko,nl,zh-tw,pl,it,hu");
8
9 dojo.declare(
10         "dijit.form.Textarea",
11         dijit.form._FormValueWidget,
12         {
13         // summary: A resizing textarea widget
14         //
15         // description:
16         //      A textarea that resizes vertically to contain the data.
17         //      Takes nearly all the parameters (name, value, etc.) that a vanilla textarea takes.
18         //      Cols is not supported and the width should be specified with style width.
19         //      Rows is not supported since this widget adjusts the height.
20         //
21         // example:
22         // |    <textarea dojoType="dijit.form.TextArea">...</textarea>
23         //
24
25         attributeMap: dojo.mixin(dojo.clone(dijit.form._FormValueWidget.prototype.attributeMap),
26                 {style:"styleNode", 'class':"styleNode"}),
27
28         templateString: (dojo.isIE || dojo.isSafari || dojo.isFF) ?
29                                 ((dojo.isIE || dojo.isSafari || dojo.isFF >= 3) ? '<fieldset id="${id}" class="dijitInline dijitInputField dijitTextArea" dojoAttachPoint="styleNode" waiRole="presentation"><div dojoAttachPoint="editNode,focusNode,eventNode" dojoAttachEvent="onpaste:_changing,oncut:_changing" waiRole="textarea" style="text-decoration:none;display:block;overflow:auto;" contentEditable="true"></div>'
30                                         : '<span id="${id}" class="dijitReset">'+
31                                         '<iframe src="javascript:<html><head><title>${_iframeEditTitle}</title></head><body><script>var _postCreate=window.frameElement?window.frameElement.postCreate:null;if(_postCreate)_postCreate();</script></body></html>"'+
32                                                         ' dojoAttachPoint="iframe,styleNode" dojoAttachEvent="onblur:_onIframeBlur" class="dijitInline dijitInputField dijitTextArea"></iframe>')
33                                 + '<textarea name="${name}" value="${value}" dojoAttachPoint="formValueNode" style="display:none;"></textarea>'
34                                 + ((dojo.isIE || dojo.isSafari || dojo.isFF >= 3) ? '</fieldset>':'</span>')
35                         : '<textarea id="${id}" name="${name}" value="${value}" dojoAttachPoint="formValueNode,editNode,focusNode,styleNode" class="dijitInputField dijitTextArea">'+dojo.isFF+'</textarea>',
36
37         setAttribute: function(/*String*/ attr, /*anything*/ value){
38                 this.inherited(arguments);
39                 switch(attr){
40                         case "disabled":
41                                 this.formValueNode.disabled = this.disabled;
42                         case "readOnly":
43                                 if(dojo.isIE || dojo.isSafari || dojo.isFF >= 3){
44                                         this.editNode.contentEditable = (!this.disabled && !this.readOnly);
45                                 }else if(dojo.isFF){
46                                         this.iframe.contentDocument.designMode = (this.disabled || this.readOnly)? "off" : "on";
47                                 }
48                 }
49         },
50
51         focus: function(){
52                 // summary: Received focus, needed for the InlineEditBox widget
53                 if(!this.disabled && !this.readOnly){
54                         this._changing(); // set initial height
55                 }
56                 dijit.focus(this.iframe || this.focusNode);
57         },
58
59         setValue: function(/*String*/ value, /*Boolean, optional*/ priorityChange){
60                 var editNode = this.editNode;
61                 if(typeof value == "string"){
62                         editNode.innerHTML = ""; // wipe out old nodes
63                         if(value.split){
64                                 var _this=this;
65                                 var isFirst = true;
66                                 dojo.forEach(value.split("\n"), function(line){
67                                         if(isFirst){ isFirst = false; }
68                                         else{
69                                                 editNode.appendChild(dojo.doc.createElement("BR")); // preserve line breaks
70                                         }
71                                         if(line){
72                                                 editNode.appendChild(dojo.doc.createTextNode(line)); // use text nodes so that imbedded tags can be edited
73                                         }
74                                 });
75                         }else if(value){
76                                 editNode.appendChild(dojo.doc.createTextNode(value));
77                         }
78                         if(!dojo.isIE){
79                                 editNode.appendChild(dojo.doc.createElement("BR")); // so that you see a cursor
80                         }
81                 }else{
82                         // blah<BR>blah --> blah\nblah
83                         // <P>blah</P><P>blah</P> --> blah\nblah
84                         // <DIV>blah</DIV><DIV>blah</DIV> --> blah\nblah
85                         // &amp;&lt;&gt; -->&< >
86                         value = editNode.innerHTML;
87                         if(this.iframe){ // strip sizeNode
88                                 value = value.replace(/<div><\/div>\r?\n?$/i,"");
89                         }
90                         value = value.replace(/\s*\r?\n|^\s+|\s+$|&nbsp;/g,"").replace(/>\s+</g,"><").replace(/<\/(p|div)>$|^<(p|div)[^>]*>/gi,"").replace(/([^>])<div>/g,"$1\n").replace(/<\/p>\s*<p[^>]*>|<br[^>]*>|<\/div>\s*<div[^>]*>/gi,"\n").replace(/<[^>]*>/g,"").replace(/&amp;/gi,"\&").replace(/&lt;/gi,"<").replace(/&gt;/gi,">");
91                         if(!dojo.isIE){
92                                 value = value.replace(/\n$/,""); // remove added <br>
93                         }
94                 }
95                 this.value = this.formValueNode.value = value;
96                 if(this.iframe){
97                         var sizeNode = dojo.doc.createElement('div');
98                         editNode.appendChild(sizeNode);
99                         var newHeight = sizeNode.offsetTop;
100                         if(editNode.scrollWidth > editNode.clientWidth){ newHeight+=16; } // scrollbar space needed?
101                         if(this.lastHeight != newHeight){ // cache size so that we don't get a resize event because of a resize event
102                                 if(newHeight == 0){ newHeight = 16; } // height = 0 causes the browser to not set scrollHeight
103                                 dojo.contentBox(this.iframe, {h: newHeight});
104                                 this.lastHeight = newHeight;
105                         }
106                         editNode.removeChild(sizeNode);
107                 }
108                 dijit.form.Textarea.superclass.setValue.call(this, this.getValue(), priorityChange);
109         },
110
111         getValue: function(){
112                 return this.value.replace(/\r/g,"");
113         },
114
115         postMixInProperties: function(){
116                 this.inherited(arguments);
117                 // don't let the source text be converted to a DOM structure since we just want raw text
118                 if(this.srcNodeRef && this.srcNodeRef.innerHTML != ""){
119                         this.value = this.srcNodeRef.innerHTML;
120                         this.srcNodeRef.innerHTML = "";
121                 }
122                 if((!this.value || this.value == "") && this.srcNodeRef && this.srcNodeRef.value){
123                         this.value = this.srcNodeRef.value;
124                 }
125                 if(!this.value){ this.value = ""; }
126                 this.value = this.value.replace(/\r\n/g,"\n").replace(/&gt;/g,">").replace(/&lt;/g,"<").replace(/&amp;/g,"&");
127                 if(dojo.isFF == 2){
128                         // In the case of Firefox an iframe is used and when the text gets focus,
129                         // focus is fired from the document object.  There isn't a way to put a
130                         // waiRole on the document object and as a result screen readers don't
131                         // announce the role.  As a result screen reader users are lost.
132                         //
133                         // An additional problem is that the browser gives the document object a
134                         // very cryptic accessible name, e.g.
135                         // wysiwyg://13/http://archive.dojotoolkit.org/nightly/dojotoolkit/dijit/tests/form/test_InlineEditBox.html
136                         // When focus is fired from the document object, the screen reader speaks
137                         // the accessible name.  The cyptic accessile name is confusing.
138                         //
139                         // A workaround for both of these problems is to give the iframe's
140                         // document a title, the name of which is similar to a role name, i.e.
141                         // "edit area".  This will be used as the accessible name which will replace
142                         // the cryptic name and will also convey the role information to the user.
143                         // Because it is read directly to the user, the string must be localized.
144                         // In addition, since a <label> element can not be associated with an iframe, if 
145                         // this control has a label, insert the label text into the title as well.
146                         var _nlsResources = dojo.i18n.getLocalization("dijit.form", "Textarea");
147                         this._iframeEditTitle = _nlsResources.iframeEditTitle;
148                         this._iframeFocusTitle = _nlsResources.iframeFocusTitle;
149                         var label=dojo.query('label[for="'+this.id+'"]');
150                         if(label.length){
151                                 this._iframeEditTitle = label[0].innerHTML + " " + this._iframeEditTitle;
152                         }
153                         var body = this.focusNode = this.editNode = dojo.doc.createElement('BODY');
154                         body.style.margin="0px";
155                         body.style.padding="0px";
156                         body.style.border="0px";
157                 }
158         },
159
160         postCreate: function(){
161                 if(dojo.isIE || dojo.isSafari || dojo.isFF >= 3){
162                         this.domNode.style.overflowY = 'hidden';
163                 }else if(dojo.isFF){
164                         var w = this.iframe.contentWindow;
165                         var title = '';
166                         try { // #4715: peeking at the title can throw a security exception during iframe setup
167                                 title = this.iframe.contentDocument.title;
168                         } catch(e) {}
169                         if(!w || !title){
170                                 this.iframe.postCreate = dojo.hitch(this, this.postCreate);
171                                 return;
172                         }
173                         var d = w.document;
174                         d.getElementsByTagName('HTML')[0].replaceChild(this.editNode, d.getElementsByTagName('BODY')[0]);
175                         if(!this.isLeftToRight()){
176                                 d.getElementsByTagName('HTML')[0].dir = "rtl";
177                         }                       
178                         this.iframe.style.overflowY = 'hidden';
179                         this.eventNode = d;
180                         // this.connect won't destroy this handler cleanly since its on the iframe's window object
181                         // resize is a method of window, not document
182                         w.addEventListener("resize", dojo.hitch(this, this._changed), false); // resize is only on the window object
183                 }else{
184                         this.focusNode = this.domNode;
185                 }
186                 if(this.eventNode){
187                         this.connect(this.eventNode, "keypress", this._onKeyPress);
188                         this.connect(this.eventNode, "mousemove", this._changed);
189                         this.connect(this.eventNode, "focus", this._focused);
190                         this.connect(this.eventNode, "blur", this._blurred);
191                 }
192                 if(this.editNode){
193                         this.connect(this.editNode, "change", this._changed); // needed for mouse paste events per #3479
194                 }
195                 this.inherited('postCreate', arguments);
196         },
197
198         // event handlers, you can over-ride these in your own subclasses
199         _focused: function(e){
200                 dojo.addClass(this.iframe||this.domNode, "dijitInputFieldFocused");
201                 this._changed(e);
202         },
203
204         _blurred: function(e){
205                 dojo.removeClass(this.iframe||this.domNode, "dijitInputFieldFocused");
206                 this._changed(e, true);
207         },
208
209         _onIframeBlur: function(){
210                 // Reset the title back to "edit area".
211                 this.iframe.contentDocument.title = this._iframeEditTitle;
212         },
213
214         _onKeyPress: function(e){
215                 if(e.keyCode == dojo.keys.TAB && !e.shiftKey && !e.ctrlKey && !e.altKey && this.iframe){
216                         // Pressing the tab key in the iframe (with designMode on) will cause the
217                         // entry of a tab character so we have to trap that here.  Since we don't
218                         // know the next focusable object we put focus on the iframe and then the
219                         // user has to press tab again (which then does the expected thing).
220                         // A problem with that is that the screen reader user hears "edit area"
221                         // announced twice which causes confusion.  By setting the
222                         // contentDocument's title to "edit area frame" the confusion should be
223                         // eliminated.
224                         this.iframe.contentDocument.title = this._iframeFocusTitle;
225                         // Place focus on the iframe. A subsequent tab or shift tab will put focus
226                         // on the correct control.
227                         // Note: Can't use this.focus() because that results in a call to
228                         // dijit.focus and if that receives an iframe target it will set focus
229                         // on the iframe's contentWindow.
230                         this.iframe.focus();  // this.focus(); won't work
231                         dojo.stopEvent(e);
232                 }else if(e.keyCode == dojo.keys.ENTER){
233                         e.stopPropagation();
234                 }else if(this.inherited("_onKeyPress", arguments) && this.iframe){
235                         // #3752:
236                         // The key press will not make it past the iframe.
237                         // If a widget is listening outside of the iframe, (like InlineEditBox)
238                         // it will not hear anything.
239                         // Create an equivalent event so everyone else knows what is going on.
240                         var te = dojo.doc.createEvent("KeyEvents");
241                         te.initKeyEvent("keypress", true, true, null, e.ctrlKey, e.altKey, e.shiftKey, e.metaKey, e.keyCode, e.charCode);
242                         this.iframe.dispatchEvent(te);
243                 }
244                 this._changing();
245         },
246
247         _changing: function(e){
248                 // summary: event handler for when a change is imminent
249                 setTimeout(dojo.hitch(this, "_changed", e, false), 1);
250         },
251
252         _changed: function(e, priorityChange){
253                 // summary: event handler for when a change has already happened
254                 if(this.iframe && this.iframe.contentDocument.designMode != "on" && !this.disabled && !this.readOnly){
255                         this.iframe.contentDocument.designMode="on"; // in case this failed on init due to being hidden
256                 }
257                 this.setValue(null, priorityChange || false);
258         }
259 });
260
261 }