Subversion Repositories Applications.papyrus

Rev

Details | Last modification | View Log | RSS feed

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