Subversion Repositories Applications.papyrus

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2150 mathias 1
if(!dojo._hasResource["dijit._base.popup"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
2
dojo._hasResource["dijit._base.popup"] = true;
3
dojo.provide("dijit._base.popup");
4
 
5
dojo.require("dijit._base.focus");
6
dojo.require("dijit._base.place");
7
dojo.require("dijit._base.window");
8
 
9
dijit.popup = new function(){
10
	// summary:
11
	//		This class is used to show/hide widgets as popups.
12
	//
13
 
14
	var stack = [],
15
		beginZIndex=1000,
16
		idGen = 1;
17
 
18
	this.open = function(/*Object*/ args){
19
		// summary:
20
		//		Popup the widget at the specified position
21
		//
22
		// args: Object
23
		//		popup: Widget
24
		//			widget to display,
25
		//		parent: Widget
26
		//			the button etc. that is displaying this popup
27
		//		around: DomNode
28
		//			DOM node (typically a button); place popup relative to this node
29
		//		orient: Object
30
		//			structure specifying possible positions of popup relative to "around" node
31
		//		onCancel: Function
32
		//			callback when user has canceled the popup by
33
		//				1. hitting ESC or
34
		//				2. by using the popup widget's proprietary cancel mechanism (like a cancel button in a dialog);
35
		//				   ie: whenever popupWidget.onCancel() is called, args.onCancel is called
36
		//		onClose: Function
37
		//			callback whenever this popup is closed
38
		//		onExecute: Function
39
		//			callback when user "executed" on the popup/sub-popup by selecting a menu choice, etc. (top menu only)
40
		//
41
		// examples:
42
		//		1. opening at the mouse position
43
		//			dijit.popup.open({popup: menuWidget, x: evt.pageX, y: evt.pageY});
44
		//		2. opening the widget as a dropdown
45
		//			dijit.popup.open({parent: this, popup: menuWidget, around: this.domNode, onClose: function(){...}  });
46
		//
47
		//	Note that whatever widget called dijit.popup.open() should also listen to it's own _onBlur callback
48
		//	(fired from _base/focus.js) to know that focus has moved somewhere else and thus the popup should be closed.
49
 
50
		var widget = args.popup,
51
			orient = args.orient || {'BL':'TL', 'TL':'BL'},
52
			around = args.around,
53
			id = (args.around && args.around.id) ? (args.around.id+"_dropdown") : ("popup_"+idGen++);
54
 
55
		// make wrapper div to hold widget and possibly hold iframe behind it.
56
		// we can't attach the iframe as a child of the widget.domNode because
57
		// widget.domNode might be a <table>, <ul>, etc.
58
		var wrapper = dojo.doc.createElement("div");
59
		wrapper.id = id;
60
		wrapper.className="dijitPopup";
61
		wrapper.style.zIndex = beginZIndex + stack.length;
62
		wrapper.style.visibility = "hidden";
63
		if(args.parent){
64
			wrapper.dijitPopupParent=args.parent.id;
65
		}
66
		dojo.body().appendChild(wrapper);
67
 
68
		widget.domNode.style.display="";
69
		wrapper.appendChild(widget.domNode);
70
 
71
		var iframe = new dijit.BackgroundIframe(wrapper);
72
 
73
		// position the wrapper node
74
		var best = around ?
75
			dijit.placeOnScreenAroundElement(wrapper, around, orient, widget.orient ? dojo.hitch(widget, "orient") : null) :
76
			dijit.placeOnScreen(wrapper, args, orient == 'R' ? ['TR','BR','TL','BL'] : ['TL','BL','TR','BR']);
77
 
78
		wrapper.style.visibility = "visible";
79
		// TODO: use effects to fade in wrapper
80
 
81
		var handlers = [];
82
 
83
		// Compute the closest ancestor popup that's *not* a child of another popup.
84
		// Ex: For a TooltipDialog with a button that spawns a tree of menus, find the popup of the button.
85
		function getTopPopup(){
86
			for(var pi=stack.length-1; pi > 0 && stack[pi].parent === stack[pi-1].widget; pi--);
87
			return stack[pi];
88
		}
89
 
90
		// provide default escape and tab key handling
91
		// (this will work for any widget, not just menu)
92
		handlers.push(dojo.connect(wrapper, "onkeypress", this, function(evt){
93
			if(evt.keyCode == dojo.keys.ESCAPE && args.onCancel){
94
				args.onCancel();
95
			}else if(evt.keyCode == dojo.keys.TAB){
96
				dojo.stopEvent(evt);
97
				var topPopup = getTopPopup();
98
				if(topPopup && topPopup.onCancel){
99
					topPopup.onCancel();
100
				}
101
			}
102
		}));
103
 
104
		// watch for cancel/execute events on the popup and notify the caller
105
		// (for a menu, "execute" means clicking an item)
106
		if(widget.onCancel){
107
			handlers.push(dojo.connect(widget, "onCancel", null, args.onCancel));
108
		}
109
 
110
		handlers.push(dojo.connect(widget, widget.onExecute ? "onExecute" : "onChange", null, function(){
111
			var topPopup = getTopPopup();
112
			if(topPopup && topPopup.onExecute){
113
				topPopup.onExecute();
114
			}
115
		}));
116
 
117
		stack.push({
118
			wrapper: wrapper,
119
			iframe: iframe,
120
			widget: widget,
121
			parent: args.parent,
122
			onExecute: args.onExecute,
123
			onCancel: args.onCancel,
124
 			onClose: args.onClose,
125
			handlers: handlers
126
		});
127
 
128
		if(widget.onOpen){
129
			widget.onOpen(best);
130
		}
131
 
132
		return best;
133
	};
134
 
135
	this.close = function(/*Widget*/ popup){
136
		// summary:
137
		//		Close specified popup and any popups that it parented
138
		while(dojo.some(stack, function(elem){return elem.widget == popup;})){
139
			var top = stack.pop(),
140
				wrapper = top.wrapper,
141
				iframe = top.iframe,
142
				widget = top.widget,
143
				onClose = top.onClose;
144
 
145
			if(widget.onClose){
146
				widget.onClose();
147
			}
148
			dojo.forEach(top.handlers, dojo.disconnect);
149
 
150
			// #2685: check if the widget still has a domNode so ContentPane can change its URL without getting an error
151
			if(!widget||!widget.domNode){ return; }
152
			dojo.style(widget.domNode, "display", "none");
153
			dojo.body().appendChild(widget.domNode);
154
			iframe.destroy();
155
			dojo._destroyElement(wrapper);
156
 
157
			if(onClose){
158
				onClose();
159
			}
160
		}
161
	};
162
}();
163
 
164
dijit._frames = new function(){
165
	// summary: cache of iframes
166
	var queue = [];
167
 
168
	this.pop = function(){
169
		var iframe;
170
		if(queue.length){
171
			iframe = queue.pop();
172
			iframe.style.display="";
173
		}else{
174
			if(dojo.isIE){
175
				var html="<iframe src='javascript:\"\"'"
176
					+ " style='position: absolute; left: 0px; top: 0px;"
177
					+ "z-index: -1; filter:Alpha(Opacity=\"0\");'>";
178
				iframe = dojo.doc.createElement(html);
179
			}else{
180
			 	var iframe = dojo.doc.createElement("iframe");
181
				iframe.src = 'javascript:""';
182
				iframe.className = "dijitBackgroundIframe";
183
			}
184
			iframe.tabIndex = -1; // Magic to prevent iframe from getting focus on tab keypress - as style didnt work.
185
			dojo.body().appendChild(iframe);
186
		}
187
		return iframe;
188
	};
189
 
190
	this.push = function(iframe){
191
		iframe.style.display="";
192
		if(dojo.isIE){
193
			iframe.style.removeExpression("width");
194
			iframe.style.removeExpression("height");
195
		}
196
		queue.push(iframe);
197
	}
198
}();
199
 
200
// fill the queue
201
if(dojo.isIE && dojo.isIE < 7){
202
	dojo.addOnLoad(function(){
203
		var f = dijit._frames;
204
		dojo.forEach([f.pop()], f.push);
205
	});
206
}
207
 
208
 
209
dijit.BackgroundIframe = function(/* DomNode */node){
210
	//	summary:
211
	//		For IE z-index schenanigans. id attribute is required.
212
	//
213
	//	description:
214
	//		new dijit.BackgroundIframe(node)
215
	//			Makes a background iframe as a child of node, that fills
216
	//			area (and position) of node
217
 
218
	if(!node.id){ throw new Error("no id"); }
219
	if((dojo.isIE && dojo.isIE < 7) || (dojo.isFF && dojo.isFF < 3 && dojo.hasClass(dojo.body(), "dijit_a11y"))){
220
		var iframe = dijit._frames.pop();
221
		node.appendChild(iframe);
222
		if(dojo.isIE){
223
			iframe.style.setExpression("width", "document.getElementById('" + node.id + "').offsetWidth");
224
			iframe.style.setExpression("height", "document.getElementById('" + node.id + "').offsetHeight");
225
		}
226
		this.iframe = iframe;
227
	}
228
};
229
 
230
dojo.extend(dijit.BackgroundIframe, {
231
	destroy: function(){
232
		//	summary: destroy the iframe
233
		if(this.iframe){
234
			dijit._frames.push(this.iframe);
235
			delete this.iframe;
236
		}
237
	}
238
});
239
 
240
}