Projekt

Obecné

Profil

Stáhnout (14 KB) Statistiky
| Větev: | Tag: | Revize:
1
/*----------------------------------------------------------------------------\
2
|                        XLoadTree 2 PRE RELEASE                              |
3
|                                                                             |
4
| This is a pre release and may not be redistributed.                         |
5
| Watch http://webfx.eae.net for the final version                            |
6
|                                                                             |
7
|-----------------------------------------------------------------------------|
8
|                   Created by Erik Arvidsson & Emil A Eklund                 |
9
|                  (http://webfx.eae.net/contact.html#erik)                   |
10
|                  (http://webfx.eae.net/contact.html#emil)                   |
11
|                      For WebFX (http://webfx.eae.net/)                      |
12
|-----------------------------------------------------------------------------|
13
| A tree menu system for IE 5.5+, Mozilla 1.4+, Opera 7.5+                    |
14
|-----------------------------------------------------------------------------|
15
|         Copyright (c) 1999 - 2005 Erik Arvidsson & Emil A Eklund            |
16
|-----------------------------------------------------------------------------|
17
| This software is provided "as is", without warranty of any kind, express or |
18
| implied, including  but not limited  to the warranties of  merchantability, |
19
| fitness for a particular purpose and noninfringement. In no event shall the |
20
| authors or  copyright  holders be  liable for any claim,  damages or  other |
21
| liability, whether  in an  action of  contract, tort  or otherwise, arising |
22
| from,  out of  or in  connection with  the software or  the  use  or  other |
23
| dealings in the software.                                                   |
24
| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
25
| This  software is  available under the  three different licenses  mentioned |
26
| below.  To use this software you must chose, and qualify, for one of those. |
27
| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
28
| The WebFX Non-Commercial License          http://webfx.eae.net/license.html |
29
| Permits  anyone the right to use the  software in a  non-commercial context |
30
| free of charge.                                                             |
31
| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
32
| The WebFX Commercial license           http://webfx.eae.net/commercial.html |
33
| Permits the  license holder the right to use  the software in a  commercial |
34
| context. Such license must be specifically obtained, however it's valid for |
35
| any number of  implementations of the licensed software.                    |
36
| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
37
| GPL - The GNU General Public License    http://www.gnu.org/licenses/gpl.txt |
38
| Permits anyone the right to use and modify the software without limitations |
39
| as long as proper  credits are given  and the original  and modified source |
40
| code are included. Requires  that the final product, software derivate from |
41
| the original  source or any  software  utilizing a GPL  component, such  as |
42
| this, is also licensed under the GPL license.                               |
43
|-----------------------------------------------------------------------------|
44
| 2004-02-21 | Pre release distributed to a few selected tester               |
45
| 2005-06-06 | Removed dependency on XML Extras                               |
46
|-----------------------------------------------------------------------------|
47
| Dependencies: xtree2.js Supplies the tree control                           |
48
|-----------------------------------------------------------------------------|
49
| Created 2003-??-?? | All changes are in the log above. | Updated 2004-06-06 |
50
\----------------------------------------------------------------------------*/
51

    
52

    
53
webFXTreeConfig.loadingText = "Loading...";
54
webFXTreeConfig.loadingIcon = "images/loading.gif";
55
webFXTreeConfig.errorLoadingText = "Error Loading";
56
webFXTreeConfig.errorIcon = "images/exclamation.16.png";
57
webFXTreeConfig.reloadText = "Click to reload";
58

    
59

    
60
function WebFXLoadTree(sText, sXmlSrc, oAction, sBehavior, sIcon, sOpenIcon) {
61
	WebFXTree.call(this, sText, oAction, sBehavior, sIcon, sOpenIcon);
62

    
63
	// setup default property values
64
	this.src = sXmlSrc;
65
	this.loading = !sXmlSrc;
66
	this.loaded = !sXmlSrc;
67
	this.errorText = "";
68

    
69
	if (this.src) {
70
		/// add loading Item
71
		this._loadingItem = WebFXLoadTree.createLoadingItem();
72
		this.add(this._loadingItem);
73

    
74
		if (this.getExpanded()) {
75
			WebFXLoadTree.loadXmlDocument(this);
76
		}
77
	}
78
}
79

    
80
WebFXLoadTree.createLoadingItem = function () {
81
	return new WebFXTreeItem(webFXTreeConfig.loadingText, null, null,
82
							 webFXTreeConfig.loadingIcon);
83
};
84

    
85
_p = WebFXLoadTree.prototype = new WebFXTree;
86

    
87
_p.setExpanded = function (b) {
88
	WebFXTree.prototype.setExpanded.call(this, b);
89

    
90
	if (this.src && b) {
91
		if (!this.loaded && !this.loading) {
92
			// load
93
			WebFXLoadTree.loadXmlDocument(this);
94
		}
95
	}
96
};
97

    
98
function WebFXLoadTreeItem(sText, sXmlSrc, oAction, eParent, sIcon, sOpenIcon) {
99
	WebFXTreeItem.call(this, sText, oAction, eParent, sIcon, sOpenIcon);
100

    
101
// setup default property values
102
	this.src = sXmlSrc;
103
	this.loading = !sXmlSrc;
104
	this.loaded = !sXmlSrc;
105
	this.errorText = "";
106

    
107
	if (this.src) {
108
		/// add loading Item
109
		this._loadingItem = WebFXLoadTree.createLoadingItem();
110
		this.add(this._loadingItem);
111

    
112
		if (this.getExpanded()) {
113
			WebFXLoadTree.loadXmlDocument(this);
114
		}
115
	}
116
}
117

    
118
_p = WebFXLoadTreeItem.prototype = new WebFXTreeItem;
119

    
120
_p.setExpanded = function (b) {
121
	WebFXTreeItem.prototype.setExpanded.call(this, b);
122

    
123
	if (this.src && b) {
124
		if (!this.loaded && !this.loading) {
125
			// load
126
			WebFXLoadTree.loadXmlDocument(this);
127
		}
128
	}
129
};
130

    
131
// reloads the src file if already loaded
132
WebFXLoadTree.prototype.reload =
133
_p.reload = function () {
134
	// if loading do nothing
135
	if (this.loaded) {
136
		var t = this.getTree();
137
		var expanded = this.getExpanded();
138
		var sr = t.getSuspendRedraw();
139
		t.setSuspendRedraw(true);
140

    
141
		// remove
142
		while (this.childNodes.length > 0) {
143
			this.remove(this.childNodes[this.childNodes.length - 1]);
144
		}
145

    
146
		this.loaded = false;
147

    
148
		this._loadingItem = WebFXLoadTree.createLoadingItem();
149
		this.add(this._loadingItem);
150

    
151
		if (expanded) {
152
			this.setExpanded(true);
153
		}
154

    
155
		t.setSuspendRedraw(sr);
156
		this.update();
157
	} else if (this.open && !this.loading) {
158
		WebFXLoadTree.loadXmlDocument(this);
159
	}
160
};
161

    
162

    
163

    
164
WebFXLoadTree.prototype.setSrc =
165
_p.setSrc = function (sSrc) {
166
	var oldSrc = this.src;
167
	if (sSrc == oldSrc) return;
168

    
169
	var expanded = this.getExpanded();
170

    
171
	// remove all
172
	this._callSuspended(function () {
173
		// remove
174
		while (this.childNodes.length > 0)
175
			this.remove(this.childNodes[this.childNodes.length - 1]);
176
	});
177
	this.update();
178

    
179
	this.loaded = false;
180
	this.loading = false;
181
	if (this._loadingItem) {
182
		this._loadingItem.dispose();
183
		this._loadingItem = null;
184
	}
185
	this.src = sSrc;
186

    
187
	if (sSrc) {
188
		this._loadingItem = WebFXLoadTree.createLoadingItem();
189
		this.add(this._loadingItem);
190
	}
191

    
192
	this.setExpanded(expanded);
193
};
194

    
195
WebFXLoadTree.prototype.getSrc =
196
_p.getSrc = function () {
197
	return this.src;
198
};
199

    
200
WebFXLoadTree.prototype.dispose = function () {
201
	WebFXTree.prototype.dispose.call(this);
202
	if (this._xmlHttp)
203
	{
204
		if (this._xmlHttp.dispose) {
205
			this._xmlHttp.dispose();
206
		}
207
		try {
208
			this._xmlHttp.onreadystatechange = null;
209
			this._xmlHttp.abort();
210
		} catch (ex) {}
211
		this._xmlHttp = null;
212
	}
213
};
214

    
215
_p.dispose = function () {
216
	WebFXTreeItem.prototype.dispose.call(this);
217
	if (this._xmlHttp) {
218
		if (this._xmlHttp.dispose) {
219
			this._xmlHttp.dispose();
220
		}
221
		try {
222
			this._xmlHttp.onreadystatechange = null;
223
			this._xmlHttp.abort();
224
		} catch (ex) {}
225
		this._xmlHttp = null;
226
	}
227
};
228

    
229

    
230
// The path is divided by '/' and the item is identified by the text
231
WebFXLoadTree.prototype.openPath =
232
_p.openPath = function (sPath, bSelect, bFocus) {
233
	// remove any old pending paths to open
234
	delete this._pathToOpen;
235
	//delete this._pathToOpenById;
236
	this._selectPathOnLoad = bSelect;
237
	this._focusPathOnLoad = bFocus;
238

    
239
	if (sPath == "") {
240
		if (bSelect) {
241
			this.select();
242
		}
243
		if (bFocus) {
244
			window.setTimeout("WebFXTreeAbstractNode._onTimeoutFocus(\"" + this.getId() + "\")", 10);
245
		}
246
		return;
247
	}
248

    
249
	var parts = sPath.split("/");
250
	var remainingPath = parts.slice(1).join("/");
251

    
252
	if (sPath.charAt(0) == "/") {
253
		this.getTree().openPath(remainingPath, bSelect, bFocus);
254
	} else {
255
		// open
256
		this.setExpanded(true);
257
		if (this.loaded) {
258
			parts = sPath.split("/");
259
			var ti = this.findChildByText(parts[0]);
260
			if (!ti) {
261
				throw "Could not find child node with text \"" + parts[0] + "\"";
262
			}
263

    
264
			ti.openPath(remainingPath, bSelect, bFocus);
265
		} else {
266
			this._pathToOpen = sPath;
267
		}
268
	}
269
};
270

    
271

    
272
// Opera has some serious attribute problems. We need to use getAttribute
273
// for certain attributes
274
WebFXLoadTree._attrs = ["text", "src", "action", "id", "target"];
275

    
276
WebFXLoadTree.createItemFromElement = function (oNode) {
277
	var jsAttrs = {};
278
	var domAttrs = oNode.attributes;
279
	var i, l;
280

    
281
	l = domAttrs.length;
282
	for (i = 0; i < l; i++) {
283
		if (domAttrs[i] == null) {
284
			continue;
285
		}
286
		jsAttrs[domAttrs[i].nodeName] = domAttrs[i].nodeValue;
287
	}
288

    
289
	var name, val;
290
	for (i = 0; i < WebFXLoadTree._attrs.length; i++) {
291
		name = WebFXLoadTree._attrs[i];
292
		value = oNode.getAttribute(name);
293
		if (value) {
294
			jsAttrs[name] = value;
295
		}
296
	}
297

    
298
	var action;
299
	if (jsAttrs.onaction) {
300
		action = new Function(jsAttrs.onaction);
301
	} else if (jsAttrs.action) {
302
		action = jsAttrs.action;
303
	}
304
	var jsNode = new WebFXLoadTreeItem(jsAttrs.html || "", jsAttrs.src, action,
305
									   null, jsAttrs.icon, jsAttrs.openIcon);
306
	if (jsAttrs.text) {
307
		jsNode.setText(jsAttrs.text);
308
	}
309

    
310
	if (jsAttrs.target) {
311
		jsNode.target = jsAttrs.target;
312
	}
313
	if (jsAttrs.id) {
314
		jsNode.setId(jsAttrs.id);
315
	}
316
	if (jsAttrs.toolTip) {
317
		jsNode.toolTip = jsAttrs.toolTip;
318
	}
319
	if (jsAttrs.expanded) {
320
		jsNode.setExpanded(jsAttrs.expanded != "false");
321
	}
322
	if (jsAttrs.onload) {
323
		jsNode.onload = new Function(jsAttrs.onload);
324
	}
325
	if (jsAttrs.onerror) {
326
		jsNode.onerror = new Function(jsAttrs.onerror);
327
	}
328

    
329
	jsNode.attributes = jsAttrs;
330

    
331
	// go through childNodes
332
	var cs = oNode.childNodes;
333
	l = cs.length;
334
	for (i = 0; i < l; i++) {
335
		if (cs[i].tagName == "tree") {
336
			jsNode.add(WebFXLoadTree.createItemFromElement(cs[i]));
337
		}
338
	}
339

    
340
	return jsNode;
341
};
342

    
343
WebFXLoadTree.loadXmlDocument = function (jsNode) {
344
	if (jsNode.loading || jsNode.loaded) {
345
		return;
346
	}
347
	jsNode.loading = true;
348
	var id = jsNode.getId();
349
	jsNode._xmlHttp = window.XMLHttpRequest ? new XMLHttpRequest : new window.ActiveXObject("Microsoft.XmlHttp");
350
	jsNode._xmlHttp.open("GET", jsNode.src, true);	// async
351
	jsNode._xmlHttp.onreadystatechange = new Function("WebFXLoadTree._onload(\"" + id + "\")");
352

    
353
	// call in new thread to allow ui to update
354
	window.setTimeout("WebFXLoadTree._ontimeout(\"" + id + "\")", 10);
355
};
356

    
357
WebFXLoadTree._onload = function (sId) {
358
	var jsNode = webFXTreeHandler.all[sId];
359
	if (jsNode._xmlHttp.readyState == 4) {
360
		WebFXLoadTree.documentLoaded(jsNode);
361
		webFXLoadTreeQueue.remove(jsNode);
362
		if (jsNode._xmlHttp.dispose)
363
			jsNode._xmlHttp.dispose();
364
		jsNode._xmlHttp = null;
365
	}
366
};
367

    
368
WebFXLoadTree._ontimeout = function (sId) {
369
	var jsNode = webFXTreeHandler.all[sId];
370
	webFXLoadTreeQueue.add(jsNode);
371
};
372

    
373

    
374

    
375
// Inserts an xml document as a subtree to the provided node
376
WebFXLoadTree.documentLoaded = function (jsNode) {
377
	if (jsNode.loaded) {
378
		return;
379
	}
380

    
381
	jsNode.errorText = "";
382
	jsNode.loaded = true;
383
	jsNode.loading = false;
384

    
385
	var t = jsNode.getTree();
386
	var oldSuspend = t.getSuspendRedraw();
387
	t.setSuspendRedraw(true);
388

    
389
	var doc = jsNode._xmlHttp.responseXML;
390

    
391
	// check that the load of the xml file went well
392
	if(!doc || doc.parserError && doc.parseError.errorCode != 0 || !doc.documentElement) {
393
		if (!doc || doc.parseError.errorCode == 0) {
394
			jsNode.errorText = webFXTreeConfig.errorLoadingText + " " + jsNode.src + " (" + jsNode._xmlHttp.status + ": " + jsNode._xmlHttp.statusText + ")";
395
		} else {
396
			jsNode.errorText = webFXTreeConfig.errorLoadingText + " " + jsNode.src + " (" + doc.parseError.reason + ")";
397
		}
398
	} else {
399
		// there is one extra level of tree elements
400
		var root = doc.documentElement;
401

    
402
		// loop through all tree children
403
		var count = 0;
404
		var cs = root.childNodes;
405
		var l = cs.length;
406
		for (var i = 0; i < l; i++) {
407
			if (cs[i].tagName == "tree") {
408
				jsNode.add(WebFXLoadTree.createItemFromElement(cs[i]));
409
				count++;
410
			}
411
		}
412

    
413
		// if no children we got an error
414
		if (count == 0) {
415
			jsNode.errorText = webFXTreeConfig.errorLoadingText + " " + jsNode.src + " (???)";
416
		}
417
	}
418

    
419
	if (jsNode.errorText != "") {
420
		jsNode._loadingItem.icon = webFXTreeConfig.errorIcon;
421
		jsNode._loadingItem.text = jsNode.errorText;
422
		jsNode._loadingItem.action = WebFXLoadTree._reloadParent;
423
		jsNode._loadingItem.toolTip = webFXTreeConfig.reloadText;
424

    
425
		t.setSuspendRedraw(oldSuspend);
426

    
427
		jsNode._loadingItem.update();
428

    
429
		if (typeof jsNode.onerror == "function") {
430
			jsNode.onerror();
431
		}
432
	} else {
433
		// remove dummy
434
		if (jsNode._loadingItem != null) {
435
			jsNode.remove(jsNode._loadingItem);
436
		}
437

    
438
		if (jsNode._pathToOpen) {
439
			jsNode.openPath(jsNode._pathToOpen, jsNode._selectPathOnLoad, jsNode._focusPathOnLoad);
440
		}
441

    
442
		t.setSuspendRedraw(oldSuspend);
443
		jsNode.update();
444
		if (typeof jsNode.onload == "function") {
445
			jsNode.onload();
446
		}
447
	}
448
};
449

    
450
WebFXLoadTree._reloadParent = function () {
451
	this.getParent().reload();
452
};
453

    
454

    
455

    
456

    
457

    
458

    
459

    
460
var webFXLoadTreeQueue = {
461
	_nodes: [],
462
	_ie: /msie/i.test(navigator.userAgent),
463
	_opera: /opera/i.test(navigator.userAgent),
464

    
465
	add: function (jsNode) {
466
		if (this._ie || this._opera) {
467
			this._nodes.push(jsNode);
468
			if (this._nodes.length == 1) {
469
				this._send();
470
			}
471
		} else {
472
			jsNode._xmlHttp.send(null);
473
		}
474
	},
475

    
476
	remove: function (jsNode) {
477
		if (this._ie || this._opera) {
478
			arrayHelper.remove(this._nodes, jsNode);
479
			if (this._nodes.length > 0) {
480
				this._send();
481
			}
482
		}
483
	},
484

    
485
	// IE only
486
	_send:	function () {
487
		var id = this._nodes[0].getId();
488
		var jsNode = webFXTreeHandler.all[id];
489
		if (!jsNode) {
490
			return;
491
		}
492
		// if no _xmlHttp then remove it
493
		if (!jsNode._xmlHttp) {
494
			this.remove(jsNode);
495
		} else {
496
			jsNode._xmlHttp.send(null);
497
		}
498
	}
499
};
(1-1/2)