You are viewing a plain text version of this content. The canonical link for it is here.
Posted to jetspeed-dev@portals.apache.org by ta...@apache.org on 2005/12/06 20:30:51 UTC

svn commit: r354516 [5/15] - in /portals/jetspeed-2/trunk: applications/j2-admin/src/java/org/apache/jetspeed/portlets/customizer/ applications/j2-admin/src/webapp/WEB-INF/ applications/j2-admin/src/webapp/WEB-INF/view/customizer/ applications/j2-admin...

Added: portals/jetspeed-2/trunk/applications/j2-admin/src/webapp/dojo/src/html.js
URL: http://svn.apache.org/viewcvs/portals/jetspeed-2/trunk/applications/j2-admin/src/webapp/dojo/src/html.js?rev=354516&view=auto
==============================================================================
--- portals/jetspeed-2/trunk/applications/j2-admin/src/webapp/dojo/src/html.js (added)
+++ portals/jetspeed-2/trunk/applications/j2-admin/src/webapp/dojo/src/html.js Tue Dec  6 11:29:56 2005
@@ -0,0 +1,929 @@
+dojo.provide("dojo.html");
+dojo.require("dojo.dom");
+dojo.require("dojo.style");
+dojo.require("dojo.string");
+
+dojo.lang.mixin(dojo.html, dojo.dom);
+dojo.lang.mixin(dojo.html, dojo.style);
+
+// FIXME: we are going to assume that we can throw any and every rendering
+// engine into the IE 5.x box model. In Mozilla, we do this w/ CSS.
+// Need to investigate for KHTML and Opera
+
+dojo.html.clearSelection = function(){
+	try{
+		if(window["getSelection"]){ 
+			if(dojo.render.html.safari){
+				// pulled from WebCore/ecma/kjs_window.cpp, line 2536
+				window.getSelection().collapse();
+			}else{
+				window.getSelection().removeAllRanges();
+			}
+		}else if((document.selection)&&(document.selection.clear)){
+			document.selection.clear();
+		}
+		return true;
+	}catch(e){
+		dojo.debug(e);
+		return false;
+	}
+}
+
+dojo.html.disableSelection = function(element){
+	element = element||dojo.html.body();
+	var h = dojo.render.html;
+	
+	if(h.mozilla){
+		element.style.MozUserSelect = "none";
+	}else if(h.safari){
+		element.style.KhtmlUserSelect = "none"; 
+	}else if(h.ie){
+		element.unselectable = "on";
+	}else{
+		return false;
+	}
+	return true;
+}
+
+dojo.html.enableSelection = function(element){
+	element = element||dojo.html.body();
+	
+	var h = dojo.render.html;
+	if(h.mozilla){ 
+		element.style.MozUserSelect = ""; 
+	}else if(h.safari){
+		element.style.KhtmlUserSelect = "";
+	}else if(h.ie){
+		element.unselectable = "off";
+	}else{
+		return false;
+	}
+	return true;
+}
+
+dojo.html.selectElement = function(element){
+	if(document.selection && dojo.html.body().createTextRange){ // IE
+		var range = dojo.html.body().createTextRange();
+		range.moveToElementText(element);
+		range.select();
+	}else if(window["getSelection"]){
+		var selection = window.getSelection();
+		// FIXME: does this work on Safari?
+		if(selection["selectAllChildren"]){ // Mozilla
+			selection.selectAllChildren(element);
+		}
+	}
+}
+
+dojo.html.isSelectionCollapsed = function(){
+	if(document["selection"]){ // IE
+		return document.selection.createRange().text == "";
+	}else if(window["getSelection"]){
+		var selection = window.getSelection();
+		if(dojo.lang.isString(selection)){ // Safari
+			return selection == "";
+		}else{ // Mozilla/W3
+			return selection.isCollapsed;
+		}
+	}
+}
+
+dojo.html.getEventTarget = function(evt){
+	if(!evt) { evt = window.event || {} };
+	if(evt.srcElement) {
+		return evt.srcElement;
+	} else if(evt.target) {
+		return evt.target;
+	}
+	return null;
+}
+
+// FIXME: should the next set of functions take an optional document to operate
+// on so as to be useful for getting this information from iframes?
+dojo.html.getScrollTop = function(){
+	return document.documentElement.scrollTop || dojo.html.body().scrollTop || 0;
+}
+
+dojo.html.getScrollLeft = function(){
+	return document.documentElement.scrollLeft || dojo.html.body().scrollLeft || 0;
+}
+
+dojo.html.getDocumentWidth = function(){
+	dojo.deprecated("dojo.html.getDocument* has been deprecated in favor of dojo.html.getViewport*");
+	return dojo.html.getViewportWidth();
+}
+
+dojo.html.getDocumentHeight = function(){
+	dojo.deprecated("dojo.html.getDocument* has been deprecated in favor of dojo.html.getViewport*");
+	return dojo.html.getViewportHeight();
+}
+
+dojo.html.getDocumentSize = function(){
+	dojo.deprecated("dojo.html.getDocument* has been deprecated in favor of dojo.html.getViewport*");
+	return dojo.html.getViewportSize();
+}
+
+dojo.html.getViewportWidth = function(){
+	var w = 0;
+
+	if(window.innerWidth){
+		w = window.innerWidth;
+	}
+
+	if(document.documentElement && document.documentElement.clientWidth){
+		// IE6 Strict
+		var w2 = document.documentElement.clientWidth;
+		// this lets us account for scrollbars
+		if(!w || w2 && w2 < w) {
+			w = w2;
+		}
+		return w;
+	}
+
+	if(document.body){
+		// IE
+		return document.body.clientWidth;
+	}
+
+	return 0;
+}
+
+dojo.html.getViewportHeight = function(){
+	if (window.innerHeight){
+		return window.innerHeight;
+	}
+
+	if (document.documentElement && document.documentElement.clientHeight){
+		// IE6 Strict
+		return document.documentElement.clientHeight;
+	}
+
+	if (document.body){
+		// IE
+		return document.body.clientHeight;
+	}
+
+	return 0;
+}
+
+dojo.html.getViewportSize = function(){
+	var ret = [dojo.html.getViewportWidth(), dojo.html.getViewportHeight()];
+	ret.w = ret[0];
+	ret.h = ret[1];
+	return ret;
+}
+
+dojo.html.getScrollOffset = function(){
+	var ret = [0, 0];
+
+	if(window.pageYOffset){
+		ret = [window.pageXOffset, window.pageYOffset];
+	} else if(document.documentElement && document.documentElement.scrollTop){
+		ret = [document.documentElement.scrollLeft, document.documentElement.scrollTop];
+	} else if(document.body){
+		ret = [document.body.scrollLeft, document.body.scrollTop];
+	}
+
+	ret.x = ret[0];
+	ret.y = ret[1];
+	return ret;
+}
+
+dojo.html.getParentOfType = function(node, type){
+	dojo.deprecated("dojo.html.getParentOfType has been deprecated in favor of dojo.html.getParentByType*");
+	return dojo.html.getParentByType(node, type);
+}
+
+dojo.html.getParentByType = function(node, type) {
+	var parent = node;
+	type = type.toLowerCase();
+	while(parent.nodeName.toLowerCase()!=type){
+		if((!parent)||(parent==(document["body"]||document["documentElement"]))){
+			return null;
+		}
+		parent = parent.parentNode;
+	}
+	return parent;
+}
+
+// RAR: this function comes from nwidgets and is more-or-less unmodified.
+// We should probably look ant Burst and f(m)'s equivalents
+dojo.html.getAttribute = function(node, attr){
+	// FIXME: need to add support for attr-specific accessors
+	if((!node)||(!node.getAttribute)){
+		// if(attr !== 'nwType'){
+		//	alert("getAttr of '" + attr + "' with bad node"); 
+		// }
+		return null;
+	}
+	var ta = typeof attr == 'string' ? attr : new String(attr);
+
+	// first try the approach most likely to succeed
+	var v = node.getAttribute(ta.toUpperCase());
+	if((v)&&(typeof v == 'string')&&(v!="")){ return v; }
+
+	// try returning the attributes value, if we couldn't get it as a string
+	if(v && typeof v == 'object' && v.value){ return v.value; }
+
+	// this should work on Opera 7, but it's a little on the crashy side
+	if((node.getAttributeNode)&&(node.getAttributeNode(ta))){
+		return (node.getAttributeNode(ta)).value;
+	}else if(node.getAttribute(ta)){
+		return node.getAttribute(ta);
+	}else if(node.getAttribute(ta.toLowerCase())){
+		return node.getAttribute(ta.toLowerCase());
+	}
+	return null;
+}
+	
+/**
+ *	Determines whether or not the specified node carries a value for the
+ *	attribute in question.
+ */
+dojo.html.hasAttribute = function(node, attr){
+	var v = dojo.html.getAttribute(node, attr);
+	return v ? true : false;
+}
+	
+/**
+ * Returns the string value of the list of CSS classes currently assigned
+ * directly to the node in question. Returns an empty string if no class attribute
+ * is found;
+ */
+dojo.html.getClass = function(node){
+	if(node.className){
+		return node.className;
+	}else if(dojo.html.hasAttribute(node, "class")){
+		return dojo.html.getAttribute(node, "class");
+	}
+	return "";
+}
+
+/**
+ * Returns whether or not the specified classname is a portion of the
+ * class list currently applied to the node. Does not cover cascaded
+ * styles, only classes directly applied to the node.
+ */
+dojo.html.hasClass = function(node, classname){
+	var classes = dojo.html.getClass(node).split(/\s+/g);
+	for(var x=0; x<classes.length; x++){
+		if(classname == classes[x]){ return true; }
+	}
+	return false;
+}
+
+/**
+ * Adds the specified class to the beginning of the class list on the
+ * passed node. This gives the specified class the highest precidence
+ * when style cascading is calculated for the node. Returns true or
+ * false; indicating success or failure of the operation, respectively.
+ */
+dojo.html.prependClass = function(node, classStr){
+	if(!node){ return null; }
+	if(dojo.html.hasAttribute(node,"class")||node.className){
+		classStr += " " + (node.className||dojo.html.getAttribute(node, "class"));
+	}
+	return dojo.html.setClass(node, classStr);
+}
+
+/**
+ * Adds the specified class to the end of the class list on the
+ *	passed &node;. Returns &true; or &false; indicating success or failure.
+ */
+dojo.html.addClass = function(node, classStr){
+	if (!node) { throw new Error("addClass: node does not exist"); }
+	if (dojo.html.hasClass(node, classStr)) {
+	  return false;
+	}
+	if(dojo.html.hasAttribute(node,"class")||node.className){
+		classStr = (node.className||dojo.html.getAttribute(node, "class")) + " " + classStr;
+	}
+	return dojo.html.setClass(node, classStr);
+}
+
+/**
+ *	Clobbers the existing list of classes for the node, replacing it with
+ *	the list given in the 2nd argument. Returns true or false
+ *	indicating success or failure.
+ */
+dojo.html.setClass = function(node, classStr){
+	if(!node){ return false; }
+	var cs = new String(classStr);
+	try{
+		if(typeof node.className == "string"){
+			node.className = cs;
+		}else if(node.setAttribute){
+			node.setAttribute("class", classStr);
+			node.className = cs;
+		}else{
+			return false;
+		}
+	}catch(e){
+		dojo.debug("dojo.html.setClass() failed", e);
+	}
+	return true;
+}
+
+/**
+ * Removes the className from the node;. Returns
+ * true or false indicating success or failure.
+ */ 
+dojo.html.removeClass = function(node, classStr, allowPartialMatches){
+	if(!node){ return false; }
+	var classStr = dojo.string.trim(new String(classStr));
+
+	try{
+		var cs = String( node.className ).split(" ");
+		var nca	= [];
+		if(allowPartialMatches){
+			for(var i = 0; i<cs.length; i++){
+				if(cs[i].indexOf(classStr) == -1){ 
+					nca.push(cs[i]);
+				}
+			}
+		}else{
+			for(var i=0; i<cs.length; i++){
+				if(cs[i] != classStr){ 
+					nca.push(cs[i]);
+				}
+			}
+		}
+		node.className = nca.join(" ");
+	}catch(e){
+		dojo.debug("dojo.html.removeClass() failed", e);
+	}
+
+	return true;
+}
+
+/**
+ * Replaces 'oldClass' and adds 'newClass' to node
+ */
+dojo.html.replaceClass = function(node, newClass, oldClass) {
+	dojo.html.removeClass(node, oldClass);
+	dojo.html.addClass(node, newClass);
+}
+
+// Enum type for getElementsByClass classMatchType arg:
+dojo.html.classMatchType = {
+	ContainsAll : 0, // all of the classes are part of the node's class (default)
+	ContainsAny : 1, // any of the classes are part of the node's class
+	IsOnly : 2 // only all of the classes are part of the node's class
+}
+
+
+/**
+ * Returns an array of nodes for the given classStr, children of a
+ * parent, and optionally of a certain nodeType
+ */
+dojo.html.getElementsByClass = function(classStr, parent, nodeType, classMatchType){
+	if(!parent){ parent = document; }
+	var classes = classStr.split(/\s+/g);
+	var nodes = [];
+	if( classMatchType != 1 && classMatchType != 2 ) classMatchType = 0; // make it enum
+	var reClass = new RegExp("(\\s|^)((" + classes.join(")|(") + "))(\\s|$)");
+
+	// FIXME: doesn't have correct parent support!
+	if(false && document.evaluate) { // supports dom 3 xpath
+		var xpath = "//" + (nodeType || "*") + "[contains(";
+		if(classMatchType != dojo.html.classMatchType.ContainsAny){
+			xpath += "concat(' ',@class,' '), ' " +
+				classes.join(" ') and contains(concat(' ',@class,' '), ' ") +
+				" ')]";
+		}else{
+			xpath += "concat(' ',@class,' '), ' " +
+				classes.join(" ')) or contains(concat(' ',@class,' '), ' ") +
+				" ')]";
+		}
+		//dojo.debug("xpath: " + xpath);
+
+		var xpathResult = document.evaluate(xpath, parent, null,
+			XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
+
+		outer:
+		for(var node = null, i = 0; node = xpathResult.snapshotItem(i); i++){
+			if(classMatchType != dojo.html.classMatchType.IsOnly){
+				nodes.push(node);
+			}else{
+				if(!dojo.html.getClass(node)){ continue outer; }
+
+				var nodeClasses = dojo.html.getClass(node).split(/\s+/g);
+				for(var j = 0; j < nodeClasses.length; j++) {
+					if( !nodeClasses[j].match(reClass) ) {
+						continue outer;
+					}
+				}
+				nodes.push(node);
+			}
+		}
+	}else{
+		if(!nodeType){ nodeType = "*"; }
+		var candidateNodes = parent.getElementsByTagName(nodeType);
+
+		outer:
+		for(var i = 0; i < candidateNodes.length; i++) {
+			var node = candidateNodes[i];
+			if( !dojo.html.getClass(node) ) { continue outer; }
+			var nodeClasses = dojo.html.getClass(node).split(/\s+/g);
+			var matches = 0;
+
+			for(var j = 0; j < nodeClasses.length; j++) {
+				if( reClass.test(nodeClasses[j]) ) {
+					if( classMatchType == dojo.html.classMatchType.ContainsAny ) {
+						nodes.push(node);
+						continue outer;
+					} else {
+						matches++;
+					}
+				} else {
+					if( classMatchType == dojo.html.classMatchType.IsOnly ) {
+						continue outer;
+					}
+				}
+			}
+
+			if( matches == classes.length ) {
+				if( classMatchType == dojo.html.classMatchType.IsOnly && matches == nodeClasses.length ) {
+					nodes.push(node);
+				} else if( classMatchType == dojo.html.classMatchType.ContainsAll ) {
+					nodes.push(node);
+				}
+			}
+		}
+	}
+	return nodes;
+}
+dojo.html.getElementsByClassName = dojo.html.getElementsByClass;
+
+/**
+ * Calculates the mouse's direction of gravity relative to the centre
+ * of the given node.
+ * <p>
+ * If you wanted to insert a node into a DOM tree based on the mouse
+ * position you might use the following code:
+ * <pre>
+ * if (gravity(node, e) & gravity.NORTH) { [insert before]; }
+ * else { [insert after]; }
+ * </pre>
+ *
+ * @param node The node
+ * @param e		The event containing the mouse coordinates
+ * @return		 The directions, NORTH or SOUTH and EAST or WEST. These
+ *						 are properties of the function.
+ */
+dojo.html.gravity = function(node, e){
+	var mousex = e.pageX || e.clientX + dojo.html.body().scrollLeft;
+	var mousey = e.pageY || e.clientY + dojo.html.body().scrollTop;
+	
+	with (dojo.html) {
+		var nodecenterx = getAbsoluteX(node) + (getInnerWidth(node) / 2);
+		var nodecentery = getAbsoluteY(node) + (getInnerHeight(node) / 2);
+	}
+	
+	with (dojo.html.gravity) {
+		return ((mousex < nodecenterx ? WEST : EAST) |
+			(mousey < nodecentery ? NORTH : SOUTH));
+	}
+}
+
+dojo.html.gravity.NORTH = 1;
+dojo.html.gravity.SOUTH = 1 << 1;
+dojo.html.gravity.EAST = 1 << 2;
+dojo.html.gravity.WEST = 1 << 3;
+	
+dojo.html.overElement = function(element, e){
+	var mousex = e.pageX || e.clientX + dojo.html.body().scrollLeft;
+	var mousey = e.pageY || e.clientY + dojo.html.body().scrollTop;
+	
+	with(dojo.html){
+		var top = getAbsoluteY(element);
+		var bottom = top + getInnerHeight(element);
+		var left = getAbsoluteX(element);
+		var right = left + getInnerWidth(element);
+	}
+	
+	return (mousex >= left && mousex <= right &&
+		mousey >= top && mousey <= bottom);
+}
+
+/**
+ * Attempts to return the text as it would be rendered, with the line breaks
+ * sorted out nicely. Unfinished.
+ */
+dojo.html.renderedTextContent = function(node){
+	var result = "";
+	if (node == null) { return result; }
+	for (var i = 0; i < node.childNodes.length; i++) {
+		switch (node.childNodes[i].nodeType) {
+			case 1: // ELEMENT_NODE
+			case 5: // ENTITY_REFERENCE_NODE
+				switch (dojo.style.getStyle(node.childNodes[i], "display")) {
+					case "block": case "list-item": case "run-in":
+					case "table": case "table-row-group": case "table-header-group":
+					case "table-footer-group": case "table-row": case "table-column-group":
+					case "table-column": case "table-cell": case "table-caption":
+						// TODO: this shouldn't insert double spaces on aligning blocks
+						result += "\n";
+						result += dojo.html.renderedTextContent(node.childNodes[i]);
+						result += "\n";
+						break;
+					
+					case "none": break;
+					
+					default:
+						result += dojo.html.renderedTextContent(node.childNodes[i]);
+						break;
+				}
+				break;
+			case 3: // TEXT_NODE
+			case 2: // ATTRIBUTE_NODE
+			case 4: // CDATA_SECTION_NODE
+				var text = node.childNodes[i].nodeValue;
+				switch (dojo.style.getStyle(node, "text-transform")){
+					case "capitalize": text = dojo.string.capitalize(text); break;
+					case "uppercase": text = text.toUpperCase(); break;
+					case "lowercase": text = text.toLowerCase(); break;
+					default: break; // leave as is
+				}
+				// TODO: implement
+				switch (dojo.style.getStyle(node, "text-transform")){
+					case "nowrap": break;
+					case "pre-wrap": break;
+					case "pre-line": break;
+					case "pre": break; // leave as is
+					default:
+						// remove whitespace and collapse first space
+						text = text.replace(/\s+/, " ");
+						if (/\s$/.test(result)) { text.replace(/^\s/, ""); }
+						break;
+				}
+				result += text;
+				break;
+			default:
+				break;
+		}
+	}
+	return result;
+}
+
+dojo.html.setActiveStyleSheet = function(title){
+	var i, a, main;
+	for(i=0; (a = document.getElementsByTagName("link")[i]); i++){
+		if(a.getAttribute("rel").indexOf("style") != -1 && a.getAttribute("title")){
+			a.disabled = true;
+			if (a.getAttribute("title") == title) { a.disabled = false; }
+		}
+	}
+}
+
+dojo.html.getActiveStyleSheet = function(){
+	var i, a;
+	// FIXME: getElementsByTagName returns a live collection. This seems like a
+	// bad key for iteration.
+	for(i=0; (a = document.getElementsByTagName("link")[i]); i++){
+		if (a.getAttribute("rel").indexOf("style") != -1 &&
+			a.getAttribute("title") && !a.disabled) { return a.getAttribute("title"); }
+	}
+	return null;
+}
+
+dojo.html.getPreferredStyleSheet = function(){
+	var i, a;
+	for(i=0; (a = document.getElementsByTagName("link")[i]); i++){
+		if(a.getAttribute("rel").indexOf("style") != -1
+			&& a.getAttribute("rel").indexOf("alt") == -1
+			&& a.getAttribute("title")) { return a.getAttribute("title"); }
+	}
+	return null;
+}
+
+dojo.html.body = function(){
+	return document.body || document.getElementsByTagName("body")[0];
+}
+
+dojo.html.createNodesFromText = function(txt, wrap){
+	var tn = document.createElement("div");
+	// tn.style.display = "none";
+	tn.style.visibility= "hidden";
+	document.body.appendChild(tn);
+	tn.innerHTML = txt;
+	tn.normalize();
+	if(wrap){ 
+		var ret = [];
+		// start hack
+		var fc = tn.firstChild;
+		ret[0] = ((fc.nodeValue == " ")||(fc.nodeValue == "\t")) ? fc.nextSibling : fc;
+		// end hack
+		// tn.style.display = "none";
+		document.body.removeChild(tn);
+		return ret;
+	}
+	var nodes = [];
+	for(var x=0; x<tn.childNodes.length; x++){
+		nodes.push(tn.childNodes[x].cloneNode(true));
+	}
+	tn.style.display = "none";
+	document.body.removeChild(tn);
+	return nodes;
+}
+
+// FIXME: this should be removed after 0.2 release
+if(!dojo.evalObjPath("dojo.dom.createNodesFromText")){
+	dojo.dom.createNodesFromText = function() {
+		dojo.deprecated("dojo.dom.createNodesFromText", "use dojo.html.createNodesFromText instead");
+		return dojo.html.createNodesFromText.apply(dojo.html, arguments);
+	}
+}
+
+dojo.html.getAncestorsByTag = function(node, tag, returnFirstHit){
+	tag = tag.toLowerCase();
+	return dojo.dom.getAncestors(node, function(el) {
+		return el.tagName && (el.tagName.toLowerCase() == tag);
+	}, returnFirstHit);
+}
+
+dojo.html.getFirstAncestorByTag = function(node, tag){
+	return dojo.html.getAncestorsByTag(node, tag, true);
+}
+
+dojo.html.isVisible = function(node){
+	// FIXME: this should also look at visibility!
+	return dojo.style.getComputedStyle(node||this.domNode, "display") != "none";
+}
+
+dojo.html.show  = function(node){
+	if(node.style){
+		node.style.display = dojo.lang.inArray(node.tagName.toLowerCase(), ['tr', 'td', 'th']) ? "" : "block";
+	}
+}
+
+dojo.html.hide = function(node){
+	if(node.style){
+		node.style.display = "none";
+	}
+}
+
+// in: coordinate array [x,y,w,h] or dom node
+// return: coordinate array
+dojo.html.toCoordinateArray = function(coords, includeScroll) {
+	if(dojo.lang.isArray(coords)){
+		// coords is already an array (of format [x,y,w,h]), just return it
+		while ( coords.length < 4 ) { coords.push(0); }
+		while ( coords.length > 4 ) { coords.pop(); }
+		var ret = coords;
+	} else {
+		// coords is an dom object (or dom object id); return it's coordinates
+		var node = dojo.byId(coords);
+		var ret = [
+			dojo.html.getAbsoluteX(node, includeScroll),
+			dojo.html.getAbsoluteY(node, includeScroll),
+			dojo.html.getInnerWidth(node),
+			dojo.html.getInnerHeight(node)
+		];
+	}
+	ret.x = ret[0];
+	ret.y = ret[1];
+	ret.w = ret[2];
+	ret.h = ret[3];
+	return ret;
+};
+
+/* TODO: merge keepOnScreen and keepOnScreenPoint to make 1 function that allows you
+ * to define which corner(s) you want to bind to. Something like so:
+ *
+ * kes(node, desiredX, desiredY, "TR")
+ * kes(node, [desiredX, desiredY], ["TR", "BL"])
+ *
+ * TODO: make this function have variable call sigs
+ *
+ * kes(node, ptArray, cornerArray, padding, hasScroll)
+ * kes(node, ptX, ptY, cornerA, cornerB, cornerC, paddingArray, hasScroll)
+ */
+
+/**
+ * Keeps 'node' in the visible area of the screen while trying to
+ * place closest to desiredX, desiredY. The input coordinates are
+ * expected to be the desired screen position, not accounting for
+ * scrolling. If you already accounted for scrolling, set 'hasScroll'
+ * to true. Set padding to either a number or array for [paddingX, paddingY]
+ * to put some buffer around the element you want to position.
+ * NOTE: node is assumed to be absolutely or relatively positioned.
+ *
+ * Alternate call sig:
+ *  keepOnScreen(node, [x, y], padding, hasScroll)
+ *
+ * Examples:
+ *  keepOnScreen(node, 100, 200)
+ *  keepOnScreen("myId", [800, 623], 5)
+ *  keepOnScreen(node, 234, 3284, [2, 5], true)
+ */
+dojo.html.keepOnScreen = function(node, desiredX, desiredY, padding, hasScroll) {
+	if(dojo.lang.isArray(desiredX)) {
+		hasScroll = padding;
+		padding = desiredY;
+		desiredY = desiredX[1];
+		desiredX = desiredX[0];
+	}
+
+	if(!isNaN(padding)) {
+		padding = [Number(padding), Number(padding)];
+	} else if(!dojo.lang.isArray(padding)) {
+		padding = [0, 0];
+	}
+
+	var scroll = dojo.html.getScrollOffset();
+	var view = dojo.html.getViewportSize();
+
+	node = dojo.byId(node);
+	var w = node.offsetWidth + padding[0];
+	var h = node.offsetHeight + padding[1];
+
+	if(hasScroll) {
+		desiredX -= scroll.x;
+		desiredY -= scroll.y;
+	}
+
+	var x = desiredX + w;
+	if(x > view.w) {
+		x = view.w - w;
+	} else {
+		x = desiredX;
+	}
+	x = Math.max(padding[0], x) + scroll.x;
+
+	var y = desiredY + h;
+	if(y > view.h) {
+		y = view.h - h;
+	} else {
+		y = desiredY;
+	}
+	y = Math.max(padding[1], y) + scroll.y;
+
+	node.style.left = x + "px";
+	node.style.top = y + "px";
+
+	var ret = [x, y];
+	ret.x = x;
+	ret.y = y;
+	return ret;
+}
+
+/**
+ * Like keepOnScreenPoint except that it attempts to keep one of the node's
+ * corners at desiredX, desiredY. Also note that padding is only taken into
+ * account if none of the corners can be kept and thus keepOnScreenPoint falls
+ * back to keepOnScreen to place the node.
+ *
+ * Examples placing node at mouse position (where e = [Mouse event]):
+ *  keepOnScreenPoint(node, e.clientX, e.clientY);
+ */
+dojo.html.keepOnScreenPoint = function(node, desiredX, desiredY, padding, hasScroll) {
+	if(dojo.lang.isArray(desiredX)) {
+		hasScroll = padding;
+		padding = desiredY;
+		desiredY = desiredX[1];
+		desiredX = desiredX[0];
+	}
+
+	var scroll = dojo.html.getScrollOffset();
+	var view = dojo.html.getViewportSize();
+
+	node = dojo.byId(node);
+	var w = node.offsetWidth;
+	var h = node.offsetHeight;
+
+	if(hasScroll) {
+		desiredX -= scroll.x;
+		desiredY -= scroll.y;
+	}
+
+	var x = -1, y = -1;
+	//dojo.debug(desiredX + w, "<=", view.w, "&&", desiredY + h, "<=", view.h);
+	if(desiredX + w <= view.w && desiredY + h <= view.h) { // TL
+		x = desiredX;
+		y = desiredY;
+		//dojo.debug("TL", x, y);
+	}
+
+	//dojo.debug(desiredX, "<=", view.w, "&&", desiredY + h, "<=", view.h);
+	if((x < 0 || y < 0) && desiredX <= view.w && desiredY + h <= view.h) { // TR
+		x = desiredX - w;
+		y = desiredY;
+		//dojo.debug("TR", x, y);
+	}
+
+	//dojo.debug(desiredX + w, "<=", view.w, "&&", desiredY, "<=", view.h);
+	if((x < 0 || y < 0) && desiredX + w <= view.w && desiredY <= view.h) { // BL
+		x = desiredX;
+		y = desiredY - h;
+		//dojo.debug("BL", x, y);
+	}
+
+	//dojo.debug(desiredX, "<=", view.w, "&&", desiredY, "<=", view.h);
+	if((x < 0 || y < 0) && desiredX <= view.w && desiredY <= view.h) { // BR
+		x = desiredX - w;
+		y = desiredY - h;
+		//dojo.debug("BR", x, y);
+	}
+
+	if(x < 0 || y < 0 || (x + w > view.w) || (y + h > view.h)) {
+		return dojo.html.keepOnScreen(node, desiredX, desiredY, padding, hasScroll);
+	}
+
+	x += scroll.x;
+	y += scroll.y;
+
+	node.style.left = x + "px";
+	node.style.top = y + "px";
+
+	var ret = [x, y];
+	ret.x = x;
+	ret.y = y;
+	return ret;
+}
+
+/**
+ * For IE z-index schenanigans
+ * See Dialog widget for sample use
+ */
+dojo.html.BackgroundIframe = function() {
+	if(this.ie) {
+		this.iframe = document.createElement("<iframe frameborder='0' src='about:blank'>");
+		var s = this.iframe.style;
+		s.position = "absolute";
+		s.left = s.top = "0px";
+		s.zIndex = 2;
+		s.display = "none";
+		dojo.style.setOpacity(this.iframe, 0.0);
+		dojo.html.body().appendChild(this.iframe);
+	} else {
+		this.enabled = false;
+	}
+}
+dojo.lang.extend(dojo.html.BackgroundIframe, {
+	ie: dojo.render.html.ie,
+	enabled: true,
+	visibile: false,
+	iframe: null,
+	sizeNode: null,
+	sizeCoords: null,
+
+	size: function(node /* or coords */) {
+		if(!this.ie || !this.enabled) { return; }
+
+		if(dojo.dom.isNode(node)) {
+			this.sizeNode = node;
+		} else if(arguments.length > 0) {
+			this.sizeNode = null;
+			this.sizeCoords = node;
+		}
+		this.update();
+	},
+
+	update: function() {
+		if(!this.ie || !this.enabled) { return; }
+
+		if(this.sizeNode) {
+			this.sizeCoords = dojo.html.toCoordinateArray(this.sizeNode, true);
+		} else if(this.sizeCoords) {
+			this.sizeCoords = dojo.html.toCoordinateArray(this.sizeCoords, true);
+		} else {
+			return;
+		}
+
+		var s = this.iframe.style;
+		var dims = this.sizeCoords;
+		s.width = dims.w + "px";
+		s.height = dims.h + "px";
+		s.left = dims.x + "px";
+		s.top = dims.y + "px";
+	},
+
+	setZIndex: function(node /* or number */) {
+		if(!this.ie || !this.enabled) { return; }
+
+		if(dojo.dom.isNode(node)) {
+			this.iframe.zIndex = dojo.html.getStyle(node, "z-index") - 1;
+		} else if(!isNaN(node)) {
+			this.iframe.zIndex = node;
+		}
+	},
+
+	show: function(node /* or coords */) {
+		if(!this.ie || !this.enabled) { return; }
+
+		this.size(node);
+		this.iframe.style.display = "block";
+	},
+
+	hide: function() {
+		if(!this.ie) { return; }
+		var s = this.iframe.style;
+		s.display = "none";
+		s.width = s.height = "1px";
+	},
+
+	remove: function() {
+		dojo.dom.removeNode(this.iframe);
+	}
+});

Added: portals/jetspeed-2/trunk/applications/j2-admin/src/webapp/dojo/src/io.js
URL: http://svn.apache.org/viewcvs/portals/jetspeed-2/trunk/applications/j2-admin/src/webapp/dojo/src/io.js?rev=354516&view=auto
==============================================================================
--- portals/jetspeed-2/trunk/applications/j2-admin/src/webapp/dojo/src/io.js (added)
+++ portals/jetspeed-2/trunk/applications/j2-admin/src/webapp/dojo/src/io.js Tue Dec  6 11:29:56 2005
@@ -0,0 +1,266 @@
+dojo.provide("dojo.io.IO");
+dojo.require("dojo.string");
+
+/******************************************************************************
+ *	Notes about dojo.io design:
+ *	
+ *	The dojo.io.* package has the unenviable task of making a lot of different
+ *	types of I/O feel natural, despite a universal lack of good (or even
+ *	reasonable!) I/O capability in the host environment. So lets pin this down
+ *	a little bit further.
+ *
+ *	Rhino:
+ *		perhaps the best situation anywhere. Access to Java classes allows you
+ *		to do anything one might want in terms of I/O, both synchronously and
+ *		async. Can open TCP sockets and perform low-latency client/server
+ *		interactions. HTTP transport is available through Java HTTP client and
+ *		server classes. Wish it were always this easy.
+ *
+ *	xpcshell:
+ *		XPCOM for I/O. A cluster-fuck to be sure.
+ *
+ *	spidermonkey:
+ *		S.O.L.
+ *
+ *	Browsers:
+ *		Browsers generally do not provide any useable filesystem access. We are
+ *		therefore limited to HTTP for moving information to and from Dojo
+ *		instances living in a browser.
+ *
+ *		XMLHTTP:
+ *			Sync or async, allows reading of arbitrary text files (including
+ *			JS, which can then be eval()'d), writing requires server
+ *			cooperation and is limited to HTTP mechanisms (POST and GET).
+ *
+ *		<iframe> hacks:
+ *			iframe document hacks allow browsers to communicate asynchronously
+ *			with a server via HTTP POST and GET operations. With significant
+ *			effort and server cooperation, low-latency data transit between
+ *			client and server can be acheived via iframe mechanisms (repubsub).
+ *
+ *		SVG:
+ *			Adobe's SVG viewer implements helpful primitives for XML-based
+ *			requests, but receipt of arbitrary text data seems unlikely w/o
+ *			<![CDATA[]]> sections.
+ *
+ *
+ *	A discussion between Dylan, Mark, Tom, and Alex helped to lay down a lot
+ *	the IO API interface. A transcript of it can be found at:
+ *		http://dojotoolkit.org/viewcvs/viewcvs.py/documents/irc/irc_io_api_log.txt?rev=307&view=auto
+ *	
+ *	Also referenced in the design of the API was the DOM 3 L&S spec:
+ *		http://www.w3.org/TR/2004/REC-DOM-Level-3-LS-20040407/load-save.html
+ ******************************************************************************/
+
+// a map of the available transport options. Transports should add themselves
+// by calling add(name)
+dojo.io.transports = [];
+dojo.io.hdlrFuncNames = [ "load", "error" ]; // we're omitting a progress() event for now
+
+dojo.io.Request = function(url, mimetype, transport, changeUrl){
+	if((arguments.length == 1)&&(arguments[0].constructor == Object)){
+		this.fromKwArgs(arguments[0]);
+	}else{
+		this.url = url;
+		if (arguments.length >= 2) { this.mimetype = mimetype; }
+		if (arguments.length >= 3) { this.transport = transport; }
+		if (arguments.length >= 4) { this.changeUrl = changeUrl; }
+	}
+}
+
+dojo.lang.extend(dojo.io.Request, {
+
+	/** The URL to hit */
+	url: "",
+	
+	/** The mime type used to interrpret the response body */
+	mimetype: "text/plain",
+	
+	/** The HTTP method to use */
+	method: "GET",
+	
+	/** An Object containing key-value pairs to be included with the request */
+	content: undefined, // Object
+	
+	/** The transport medium to use */
+	transport: undefined, // String
+	
+	/** If defined the URL of the page is physically changed */
+	changeUrl: undefined, // String
+	
+	/** A form node to use in the request */
+	formNode: undefined, // HTMLFormElement
+	
+	/** Whether the request should be made synchronously */
+	sync: false,
+	
+	bindSuccess: false,
+
+	/** Cache/look for the request in the cache before attempting to request?
+	 *  NOTE: this isn't a browser cache, this is internal and would only cache in-page
+	 */
+	useCache: false,
+
+	/** Prevent the browser from caching this by adding a query string argument to the URL */
+	preventCache: false,
+	
+	// events stuff
+	load: function(type, data, evt){ },
+	error: function (type, error){ },
+	
+	// backButton: function(){ },
+	// forwardButton: function(){ },
+	// handle: function () {},
+
+	fromKwArgs: function(kwArgs){
+		// normalize args
+		if(kwArgs["url"]){ kwArgs.url = kwArgs.url.toString(); }
+		if(!kwArgs["method"] && kwArgs["formNode"] && kwArgs["formNode"].method) {
+			kwArgs.method = kwArgs["formNode"].method;
+		}
+		
+		// backwards compatibility
+		if(!kwArgs["handle"] && kwArgs["handler"]){ kwArgs.handle = kwArgs.handler; }
+		if(!kwArgs["load"] && kwArgs["loaded"]){ kwArgs.load = kwArgs.loaded; }
+		if(!kwArgs["changeUrl"] && kwArgs["changeURL"]) { kwArgs.changeUrl = kwArgs.changeURL; }
+
+		// encoding fun!
+		if(!kwArgs["encoding"]) {
+			if(!dojo.lang.isUndefined(djConfig["bindEncoding"])) {
+				kwArgs.encoding = djConfig.bindEncoding;
+			} else {
+				kwArgs.encoding = "";
+			}
+		}
+
+		var isFunction = dojo.lang.isFunction;
+		for(var x=0; x<dojo.io.hdlrFuncNames.length; x++){
+			var fn = dojo.io.hdlrFuncNames[x];
+			if(isFunction(kwArgs[fn])){ continue; }
+			if(isFunction(kwArgs["handle"])){
+				kwArgs[fn] = kwArgs.handle;
+			}
+			// handler is aliased above, shouldn't need this check
+			/* else if(dojo.lang.isObject(kwArgs.handler)){
+				if(isFunction(kwArgs.handler[fn])){
+					kwArgs[fn] = kwArgs.handler[fn]||kwArgs.handler["handle"]||function(){};
+				}
+			}*/
+		}
+		dojo.lang.mixin(this, kwArgs);
+	}
+
+});
+
+dojo.io.Error = function(msg, type, num){
+	this.message = msg;
+	this.type =  type || "unknown"; // must be one of "io", "parse", "unknown"
+	this.number = num || 0; // per-substrate error number, not normalized
+}
+
+dojo.io.transports.addTransport = function(name){
+	this.push(name);
+	// FIXME: do we need to handle things that aren't direct children of the
+	// dojo.io namespace? (say, dojo.io.foo.fooTransport?)
+	this[name] = dojo.io[name];
+}
+
+// binding interface, the various implementations register their capabilities
+// and the bind() method dispatches
+dojo.io.bind = function(request){
+	// if the request asks for a particular implementation, use it
+	if(!(request instanceof dojo.io.Request)){
+		try{
+		request = new dojo.io.Request(request);
+		}catch(e){ dojo.debug(e); }
+	}
+	var tsName = "";
+	if(request["transport"]){
+		tsName = request["transport"];
+		if(!this[tsName]){ return request; }
+	}else{
+		// otherwise we do our best to auto-detect what available transports
+		// will handle 
+		for(var x=0; x<dojo.io.transports.length; x++){
+			var tmp = dojo.io.transports[x];
+			if((this[tmp])&&(this[tmp].canHandle(request))){
+				tsName = tmp;
+			}
+		}
+		if(tsName == ""){ return request; }
+	}
+	this[tsName].bind(request);
+	request.bindSuccess = true;
+	return request;
+}
+
+dojo.io.argsFromMap = function(map, encoding){
+	var control = new Object();
+	var mapStr = "";
+	var enc = /utf/i.test(encoding||"") ? encodeURIComponent : dojo.string.encodeAscii;
+	for(var x in map){
+		if(!control[x]){
+			mapStr+= enc(x)+"="+enc(map[x])+"&";
+		}
+	}
+
+	return mapStr;
+}
+
+/*
+dojo.io.sampleTranport = new function(){
+	this.canHandle = function(kwArgs){
+		// canHandle just tells dojo.io.bind() if this is a good transport to
+		// use for the particular type of request.
+		if(	
+			(
+				(kwArgs["mimetype"] == "text/plain") ||
+				(kwArgs["mimetype"] == "text/html") ||
+				(kwArgs["mimetype"] == "text/javascript")
+			)&&(
+				(kwArgs["method"] == "get") ||
+				( (kwArgs["method"] == "post") && (!kwArgs["formNode"]) )
+			)
+		){
+			return true;
+		}
+
+		return false;
+	}
+
+	this.bind = function(kwArgs){
+		var hdlrObj = {};
+
+		// set up a handler object
+		for(var x=0; x<dojo.io.hdlrFuncNames.length; x++){
+			var fn = dojo.io.hdlrFuncNames[x];
+			if(typeof kwArgs.handler == "object"){
+				if(typeof kwArgs.handler[fn] == "function"){
+					hdlrObj[fn] = kwArgs.handler[fn]||kwArgs.handler["handle"];
+				}
+			}else if(typeof kwArgs[fn] == "function"){
+				hdlrObj[fn] = kwArgs[fn];
+			}else{
+				hdlrObj[fn] = kwArgs["handle"]||function(){};
+			}
+		}
+
+		// build a handler function that calls back to the handler obj
+		var hdlrFunc = function(evt){
+			if(evt.type == "onload"){
+				hdlrObj.load("load", evt.data, evt);
+			}else if(evt.type == "onerr"){
+				var errObj = new dojo.io.Error("sampleTransport Error: "+evt.msg);
+				hdlrObj.error("error", errObj);
+			}
+		}
+
+		// the sample transport would attach the hdlrFunc() when sending the
+		// request down the pipe at this point
+		var tgtURL = kwArgs.url+"?"+dojo.io.argsFromMap(kwArgs.content);
+		// sampleTransport.sendRequest(tgtURL, hdlrFunc);
+	}
+
+	dojo.io.transports.addTransport("sampleTranport");
+}
+*/

Added: portals/jetspeed-2/trunk/applications/j2-admin/src/webapp/dojo/src/io/BrowserIO.js
URL: http://svn.apache.org/viewcvs/portals/jetspeed-2/trunk/applications/j2-admin/src/webapp/dojo/src/io/BrowserIO.js?rev=354516&view=auto
==============================================================================
--- portals/jetspeed-2/trunk/applications/j2-admin/src/webapp/dojo/src/io/BrowserIO.js (added)
+++ portals/jetspeed-2/trunk/applications/j2-admin/src/webapp/dojo/src/io/BrowserIO.js Tue Dec  6 11:29:56 2005
@@ -0,0 +1,608 @@
+dojo.provide("dojo.io.BrowserIO");
+
+dojo.require("dojo.io");
+dojo.require("dojo.lang");
+dojo.require("dojo.dom");
+
+try {
+	if((!djConfig.preventBackButtonFix)&&(!dojo.hostenv.post_load_)){
+		document.write("<iframe style='border: 0px; width: 1px; height: 1px; position: absolute; bottom: 0px; right: 0px; visibility: visible;' name='djhistory' id='djhistory' src='"+(dojo.hostenv.getBaseScriptUri()+'iframe_history.html')+"'></iframe>");
+	}
+}catch(e){/* squelch */}
+
+dojo.io.checkChildrenForFile = function(node){
+	var hasFile = false;
+	var inputs = node.getElementsByTagName("input");
+	dojo.lang.forEach(inputs, function(input){
+		if(hasFile){ return; }
+		if(input.getAttribute("type")=="file"){
+			hasFile = true;
+		}
+	});
+	return hasFile;
+}
+
+dojo.io.formHasFile = function(formNode){
+	return dojo.io.checkChildrenForFile(formNode);
+}
+
+// TODO: Move to htmlUtils
+dojo.io.encodeForm = function(formNode, encoding){
+	if((!formNode)||(!formNode.tagName)||(!formNode.tagName.toLowerCase() == "form")){
+		dojo.raise("Attempted to encode a non-form element.");
+	}
+	var enc = /utf/i.test(encoding||"") ? encodeURIComponent : dojo.string.encodeAscii;
+	var values = [];
+
+	for(var i = 0; i < formNode.elements.length; i++){
+		var elm = formNode.elements[i];
+		if(elm.disabled || elm.tagName.toLowerCase() == "fieldset" || !elm.name){
+			continue;
+		}
+		var name = enc(elm.name);
+		var type = elm.type.toLowerCase();
+
+		if(type == "select-multiple"){
+			for(var j = 0; j < elm.options.length; j++){
+				if(elm.options[j].selected) {
+					values.push(name + "=" + enc(elm.options[j].value));
+				}
+			}
+		}else if(dojo.lang.inArray(type, ["radio", "checkbox"])){
+			if(elm.checked){
+				values.push(name + "=" + enc(elm.value));
+			}
+		}else if(!dojo.lang.inArray(type, ["file", "submit", "reset", "button"])) {
+			values.push(name + "=" + enc(elm.value));
+		}
+	}
+
+	// now collect input type="image", which doesn't show up in the elements array
+	var inputs = formNode.getElementsByTagName("input");
+	for(var i = 0; i < inputs.length; i++) {
+		var input = inputs[i];
+		if(input.type.toLowerCase() == "image" && input.form == formNode) {
+			var name = enc(input.name);
+			values.push(name + "=" + enc(input.value));
+			values.push(name + ".x=0");
+			values.push(name + ".y=0");
+		}
+	}
+	return values.join("&") + "&";
+}
+
+dojo.io.setIFrameSrc = function(iframe, src, replace){
+	try{
+		var r = dojo.render.html;
+		// dojo.debug(iframe);
+		if(!replace){
+			if(r.safari){
+				iframe.location = src;
+			}else{
+				frames[iframe.name].location = src;
+			}
+		}else{
+			var idoc;
+			// dojo.debug(iframe.name);
+			if(r.ie){
+				idoc = iframe.contentWindow.document;
+			}else if(r.moz){
+				idoc = iframe.contentWindow;
+			}
+			idoc.location.replace(src);
+		}
+	}catch(e){ 
+		dojo.debug(e); 
+		dojo.debug("setIFrameSrc: "+e); 
+	}
+}
+
+dojo.io.XMLHTTPTransport = new function(){
+	var _this = this;
+
+	this.initialHref = window.location.href;
+	this.initialHash = window.location.hash;
+
+	this.moveForward = false;
+
+	var _cache = {}; // FIXME: make this public? do we even need to?
+	this.useCache = false; // if this is true, we'll cache unless kwArgs.useCache = false
+	this.preventCache = false; // if this is true, we'll always force GET requests to cache
+	this.historyStack = [];
+	this.forwardStack = [];
+	this.historyIframe = null;
+	this.bookmarkAnchor = null;
+	this.locationTimer = null;
+
+	/* NOTES:
+	 *	Safari 1.2: 
+	 *		back button "works" fine, however it's not possible to actually
+	 *		DETECT that you've moved backwards by inspecting window.location.
+	 *		Unless there is some other means of locating.
+	 *		FIXME: perhaps we can poll on history.length?
+	 *	IE 5.5 SP2:
+	 *		back button behavior is macro. It does not move back to the
+	 *		previous hash value, but to the last full page load. This suggests
+	 *		that the iframe is the correct way to capture the back button in
+	 *		these cases.
+	 *	IE 6.0:
+	 *		same behavior as IE 5.5 SP2
+	 * Firefox 1.0:
+	 *		the back button will return us to the previous hash on the same
+	 *		page, thereby not requiring an iframe hack, although we do then
+	 *		need to run a timer to detect inter-page movement.
+	 */
+
+	// FIXME: Should this even be a function? or do we just hard code it in the next 2 functions?
+	function getCacheKey(url, query, method) {
+		return url + "|" + query + "|" + method.toLowerCase();
+	}
+
+	function addToCache(url, query, method, http) {
+		_cache[getCacheKey(url, query, method)] = http;
+	}
+
+	function getFromCache(url, query, method) {
+		return _cache[getCacheKey(url, query, method)];
+	}
+
+	this.clearCache = function() {
+		_cache = {};
+	}
+
+	// moved successful load stuff here
+	function doLoad(kwArgs, http, url, query, useCache) {
+		if((http.status==200)||(location.protocol=="file:" && http.status==0)) {
+			var ret;
+			if(kwArgs.method.toLowerCase() == "head"){
+				var headers = http.getAllResponseHeaders();
+				ret = {};
+				ret.toString = function(){ return headers; }
+				var values = headers.split(/[\r\n]+/g);
+				for(var i = 0; i < values.length; i++) {
+					var pair = values[i].match(/^([^:]+)\s*:\s*(.+)$/i);
+					if(pair) {
+						ret[pair[1]] = pair[2];
+					}
+				}
+			}else if(kwArgs.mimetype == "text/javascript"){
+				try{
+					ret = dj_eval(http.responseText);
+				}catch(e){
+					dojo.debug(e);
+					ret = null;
+				}
+			}else if(kwArgs.mimetype == "text/json"){
+				try{
+					ret = dj_eval("("+http.responseText+")");
+				}catch(e){
+					dojo.debug(e);
+					ret = false;
+				}
+			}else if((kwArgs.mimetype == "application/xml")||
+						(kwArgs.mimetype == "text/xml")){
+				ret = http.responseXML;
+				if(!ret || typeof ret == "string") {
+					ret = dojo.dom.createDocumentFromText(http.responseText);
+				}
+			}else{
+				ret = http.responseText;
+			}
+
+			if(useCache){ // only cache successful responses
+				addToCache(url, query, kwArgs.method, http);
+			}
+			if(typeof kwArgs.load == "function"){
+				kwArgs.load("load", ret, http);
+			}
+		}else{
+			var errObj = new dojo.io.Error("XMLHttpTransport Error: "+http.status+" "+http.statusText);
+			if(typeof kwArgs.error == "function"){
+				kwArgs.error("error", errObj, http);
+			}
+		}
+	}
+
+	// set headers (note: Content-Type will get overriden if kwArgs.contentType is set)
+	function setHeaders(http, kwArgs){
+		if(kwArgs["headers"]) {
+			for(var header in kwArgs["headers"]) {
+				if(header.toLowerCase() == "content-type" && !kwArgs["contentType"]) {
+					kwArgs["contentType"] = kwArgs["headers"][header];
+				} else {
+					http.setRequestHeader(header, kwArgs["headers"][header]);
+				}
+			}
+		}
+	}
+
+	this.addToHistory = function(args){
+		var callback = args["back"]||args["backButton"]||args["handle"];
+		var hash = null;
+		if(!this.historyIframe){
+			this.historyIframe = window.frames["djhistory"];
+		}
+		if(!this.bookmarkAnchor){
+			this.bookmarkAnchor = document.createElement("a");
+			(document.body||document.getElementsByTagName("body")[0]).appendChild(this.bookmarkAnchor);
+			this.bookmarkAnchor.style.display = "none";
+		}
+		if((!args["changeUrl"])||(dojo.render.html.ie)){
+			var url = dojo.hostenv.getBaseScriptUri()+"iframe_history.html?"+(new Date()).getTime();
+			this.moveForward = true;
+			dojo.io.setIFrameSrc(this.historyIframe, url, false);
+		}
+		if(args["changeUrl"]){
+			hash = "#"+ ((args["changeUrl"]!==true) ? args["changeUrl"] : (new Date()).getTime());
+			setTimeout("window.location.href = '"+hash+"';", 1);
+			this.bookmarkAnchor.href = hash;
+			if(dojo.render.html.ie){
+				// IE requires manual setting of the hash since we are catching
+				// events from the iframe
+				var oldCB = callback;
+				var lh = null;
+				var hsl = this.historyStack.length-1;
+				if(hsl>=0){
+					while(!this.historyStack[hsl]["urlHash"]){
+						hsl--;
+					}
+					lh = this.historyStack[hsl]["urlHash"];
+				}
+				if(lh){
+					callback = function(){
+						if(window.location.hash != ""){
+							setTimeout("window.location.href = '"+lh+"';", 1);
+						}
+						oldCB();
+					}
+				}
+				// when we issue a new bind(), we clobber the forward 
+				// FIXME: is this always a good idea?
+				this.forwardStack = []; 
+				var oldFW = args["forward"]||args["forwardButton"];;
+				var tfw = function(){
+					if(window.location.hash != ""){
+						window.location.href = hash;
+					}
+					if(oldFW){ // we might not actually have one
+						oldFW();
+					}
+				}
+				if(args["forward"]){
+					args.forward = tfw;
+				}else if(args["forwardButton"]){
+					args.forwardButton = tfw;
+				}
+			}else if(dojo.render.html.moz){
+				// start the timer
+				if(!this.locationTimer){
+					this.locationTimer = setInterval("dojo.io.XMLHTTPTransport.checkLocation();", 200);
+				}
+			}
+		}
+
+		this.historyStack.push({"url": url, "callback": callback, "kwArgs": args, "urlHash": hash});
+	}
+
+	this.checkLocation = function(){
+		var hsl = this.historyStack.length;
+
+		if((window.location.hash == this.initialHash)||(window.location.href == this.initialHref)&&(hsl == 1)){
+			// FIXME: could this ever be a forward button?
+			// we can't clear it because we still need to check for forwards. Ugg.
+			// clearInterval(this.locationTimer);
+			this.handleBackButton();
+			return;
+		}
+		// first check to see if we could have gone forward. We always halt on
+		// a no-hash item.
+		if(this.forwardStack.length > 0){
+			if(this.forwardStack[this.forwardStack.length-1].urlHash == window.location.hash){
+				this.handleForwardButton();
+				return;
+			}
+		}
+		// ok, that didn't work, try someplace back in the history stack
+		if((hsl >= 2)&&(this.historyStack[hsl-2])){
+			if(this.historyStack[hsl-2].urlHash==window.location.hash){
+				this.handleBackButton();
+				return;
+			}
+		}
+	}
+
+	this.iframeLoaded = function(evt, ifrLoc){
+		var isp = ifrLoc.href.split("?");
+		if(isp.length < 2){ 
+			// alert("iframeLoaded");
+			// we hit the end of the history, so we should go back
+			if(this.historyStack.length == 1){
+				this.handleBackButton();
+			}
+			return;
+		}
+		var query = isp[1];
+		if(this.moveForward){
+			// we were expecting it, so it's not either a forward or backward
+			// movement
+			this.moveForward = false;
+			return;
+		}
+
+		var last = this.historyStack.pop();
+		// we don't have anything in history, so it could be a forward button
+		if(!last){ 
+			if(this.forwardStack.length > 0){
+				var next = this.forwardStack[this.forwardStack.length-1];
+				if(query == next.url.split("?")[1]){
+					this.handleForwardButton();
+				}
+			}
+			// regardless, we didnt' have any history, so it can't be a back button
+			return;
+		}
+		// put it back on the stack so we can do something useful with it when
+		// we call handleBackButton()
+		this.historyStack.push(last);
+		if(this.historyStack.length >= 2){
+			if(isp[1] == this.historyStack[this.historyStack.length-2].url.split("?")[1]){
+				// looks like it IS a back button press, so handle it
+				this.handleBackButton();
+			}
+		}else{
+			this.handleBackButton();
+		}
+	}
+
+	this.handleBackButton = function(){
+		var last = this.historyStack.pop();
+		if(!last){ return; }
+		if(last["callback"]){
+			last.callback();
+		}else if(last.kwArgs["backButton"]){
+			last.kwArgs["backButton"]();
+		}else if(last.kwArgs["back"]){
+			last.kwArgs["back"]();
+		}else if(last.kwArgs["handle"]){
+			last.kwArgs.handle("back");
+		}
+		this.forwardStack.push(last);
+	}
+
+	this.handleForwardButton = function(){
+		// FIXME: should we build in support for re-issuing the bind() call here?
+		// alert("alert we found a forward button call");
+		var last = this.forwardStack.pop();
+		if(!last){ return; }
+		if(last.kwArgs["forward"]){
+			last.kwArgs.forward();
+		}else if(last.kwArgs["forwardButton"]){
+			last.kwArgs.forwardButton();
+		}else if(last.kwArgs["handle"]){
+			last.kwArgs.handle("forward");
+		}
+		this.historyStack.push(last);
+	}
+
+	this.inFlight = [];
+	this.inFlightTimer = null;
+
+	this.startWatchingInFlight = function(){
+		if(!this.inFlightTimer){
+			this.inFlightTimer = setInterval("dojo.io.XMLHTTPTransport.watchInFlight();", 10);
+		}
+	}
+
+	this.watchInFlight = function(){
+		for(var x=this.inFlight.length-1; x>=0; x--){
+			var tif = this.inFlight[x];
+			if(!tif){ this.inFlight.splice(x, 1); continue; }
+			if(4==tif.http.readyState){
+				// remove it so we can clean refs
+				this.inFlight.splice(x, 1);
+				doLoad(tif.req, tif.http, tif.url, tif.query, tif.useCache);
+				if(this.inFlight.length == 0){
+					clearInterval(this.inFlightTimer);
+					this.inFlightTimer = null;
+				}
+			} // FIXME: need to implement a timeout param here!
+		}
+	}
+
+	var hasXmlHttp = dojo.hostenv.getXmlhttpObject() ? true : false;
+	this.canHandle = function(kwArgs){
+		// canHandle just tells dojo.io.bind() if this is a good transport to
+		// use for the particular type of request.
+
+		// FIXME: we need to determine when form values need to be
+		// multi-part mime encoded and avoid using this transport for those
+		// requests.
+		return hasXmlHttp
+			&& dojo.lang.inArray((kwArgs["mimetype"]||"".toLowerCase()), ["text/plain", "text/html", "application/xml", "text/xml", "text/javascript", "text/json"])
+			&& dojo.lang.inArray(kwArgs["method"].toLowerCase(), ["post", "get", "head"])
+			&& !( kwArgs["formNode"] && dojo.io.formHasFile(kwArgs["formNode"]) );
+	}
+
+	this.multipartBoundary = "45309FFF-BD65-4d50-99C9-36986896A96F";	// unique guid as a boundary value for multipart posts
+
+	this.bind = function(kwArgs){
+		if(!kwArgs["url"]){
+			// are we performing a history action?
+			if( !kwArgs["formNode"]
+				&& (kwArgs["backButton"] || kwArgs["back"] || kwArgs["changeUrl"] || kwArgs["watchForURL"])
+				&& (!djConfig.preventBackButtonFix)) {
+				this.addToHistory(kwArgs);
+				return true;
+			}
+		}
+
+		// build this first for cache purposes
+		var url = kwArgs.url;
+		var query = "";
+		if(kwArgs["formNode"]){
+			var ta = kwArgs.formNode.getAttribute("action");
+			if((ta)&&(!kwArgs["url"])){ url = ta; }
+			var tp = kwArgs.formNode.getAttribute("method");
+			if((tp)&&(!kwArgs["method"])){ kwArgs.method = tp; }
+			query += dojo.io.encodeForm(kwArgs.formNode, kwArgs.encoding);
+		}
+
+		if(url.indexOf("#") > -1) {
+			dojo.debug("Warning: dojo.io.bind: stripping hash values from url:", url);
+			url = url.split("#")[0];
+		}
+
+		if(kwArgs["file"]){
+			// force post for file transfer
+			kwArgs.method = "post";
+		}
+
+		if(!kwArgs["method"]){
+			kwArgs.method = "get";
+		}
+
+		// guess the multipart value		
+		if(kwArgs.method.toLowerCase() == "get"){
+			// GET cannot use multipart
+			kwArgs.multipart = false;
+		}else{
+			if(kwArgs["file"]){
+				// enforce multipart when sending files
+				kwArgs.multipart = true;
+			}else if(!kwArgs["multipart"]){
+				// default 
+				kwArgs.multipart = false;
+			}
+		}
+
+		if(kwArgs["backButton"] || kwArgs["back"] || kwArgs["changeUrl"]){
+			this.addToHistory(kwArgs);
+		}
+
+		do { // break-block
+
+			if(kwArgs.postContent){
+				query = kwArgs.postContent;
+				break;
+			}
+
+			if(kwArgs["content"]) {
+				query += dojo.io.argsFromMap(kwArgs.content, kwArgs.encoding);
+			}
+			
+			if(kwArgs.method.toLowerCase() == "get" || !kwArgs.multipart){
+				break;
+			}
+
+			var	t = [];
+			if(query.length){
+				var q = query.split("&");
+				for(var i = 0; i < q.length; ++i){
+					if(q[i].length){
+						var p = q[i].split("=");
+						t.push(	"--" + this.multipartBoundary,
+								"Content-Disposition: form-data; name=\"" + p[0] + "\"", 
+								"",
+								p[1]);
+					}
+				}
+			}
+
+			if(kwArgs.file){
+				if(dojo.lang.isArray(kwArgs.file)){
+					for(var i = 0; i < kwArgs.file.length; ++i){
+						var o = kwArgs.file[i];
+						t.push(	"--" + this.multipartBoundary,
+								"Content-Disposition: form-data; name=\"" + o.name + "\"; filename=\"" + ("fileName" in o ? o.fileName : o.name) + "\"",
+								"Content-Type: " + ("contentType" in o ? o.contentType : "application/octet-stream"),
+								"",
+								o.content);
+					}
+				}else{
+					var o = kwArgs.file;
+					t.push(	"--" + this.multipartBoundary,
+							"Content-Disposition: form-data; name=\"" + o.name + "\"; filename=\"" + ("fileName" in o ? o.fileName : o.name) + "\"",
+							"Content-Type: " + ("contentType" in o ? o.contentType : "application/octet-stream"),
+							"",
+							o.content);
+				}
+			}
+
+			if(t.length){
+				t.push("--"+this.multipartBoundary+"--", "");
+				query = t.join("\r\n");
+			}
+		}while(false);
+
+		// kwArgs.Connection = "close";
+
+		var async = kwArgs["sync"] ? false : true;
+
+		var preventCache = kwArgs["preventCache"] ||
+			(this.preventCache == true && kwArgs["preventCache"] != false);
+		var useCache = kwArgs["useCache"] == true ||
+			(this.useCache == true && kwArgs["useCache"] != false );
+
+		// preventCache is browser-level (add query string junk), useCache
+		// is for the local cache. If we say preventCache, then don't attempt
+		// to look in the cache, but if useCache is true, we still want to cache
+		// the response
+		if(!preventCache && useCache){
+			var cachedHttp = getFromCache(url, query, kwArgs.method);
+			if(cachedHttp){
+				doLoad(kwArgs, cachedHttp, url, query, false);
+				return;
+			}
+		}
+
+		// much of this is from getText, but reproduced here because we need
+		// more flexibility
+		var http = dojo.hostenv.getXmlhttpObject();
+		var received = false;
+
+		// build a handler function that calls back to the handler obj
+		if(async){
+			// FIXME: setting up this callback handler leaks on IE!!!
+			this.inFlight.push({
+				"req":		kwArgs,
+				"http":		http,
+				"url":		url,
+				"query":	query,
+				"useCache":	useCache
+			});
+			this.startWatchingInFlight();
+		}
+
+		if(kwArgs.method.toLowerCase() == "post"){
+			// FIXME: need to hack in more flexible Content-Type setting here!
+			http.open("POST", url, async);
+			setHeaders(http, kwArgs);
+			http.setRequestHeader("Content-Type", kwArgs.multipart ? ("multipart/form-data; boundary=" + this.multipartBoundary) : 
+				(kwArgs.contentType || "application/x-www-form-urlencoded"));
+			http.send(query);
+		}else{
+			var tmpUrl = url;
+			if(query != "") {
+				tmpUrl += (tmpUrl.indexOf("?") > -1 ? "&" : "?") + query;
+			}
+			if(preventCache) {
+				tmpUrl += (dojo.string.endsWithAny(tmpUrl, "?", "&")
+					? "" : (tmpUrl.indexOf("?") > -1 ? "&" : "?")) + "dojo.preventCache=" + new Date().valueOf();
+			}
+			http.open(kwArgs.method.toUpperCase(), tmpUrl, async);
+			setHeaders(http, kwArgs);
+			http.send(null);
+		}
+
+		if( !async ) {
+			doLoad(kwArgs, http, url, query, useCache);
+		}
+
+		kwArgs.abort = function(){
+			return http.abort();
+		}
+
+		return;
+	}
+	dojo.io.transports.addTransport("XMLHTTPTransport");
+}

Added: portals/jetspeed-2/trunk/applications/j2-admin/src/webapp/dojo/src/io/IframeIO.js
URL: http://svn.apache.org/viewcvs/portals/jetspeed-2/trunk/applications/j2-admin/src/webapp/dojo/src/io/IframeIO.js?rev=354516&view=auto
==============================================================================
--- portals/jetspeed-2/trunk/applications/j2-admin/src/webapp/dojo/src/io/IframeIO.js (added)
+++ portals/jetspeed-2/trunk/applications/j2-admin/src/webapp/dojo/src/io/IframeIO.js Tue Dec  6 11:29:56 2005
@@ -0,0 +1,194 @@
+dojo.provide("dojo.io.IframeIO");
+dojo.require("dojo.io.BrowserIO");
+dojo.require("dojo.uri.*");
+
+dojo.io.createIFrame = function(fname, onloadstr){
+	if(window[fname]){ return window[fname]; }
+	if(window.frames[fname]){ return window.frames[fname]; }
+	var r = dojo.render.html;
+	var cframe = null;
+	var turi = dojo.uri.dojoUri("iframe_history.html?noInit=true");
+	var ifrstr = ((r.ie)&&(dojo.render.os.win)) ? "<iframe name='"+fname+"' src='"+turi+"' onload='"+onloadstr+"'>" : "iframe";
+	cframe = document.createElement(ifrstr);
+	with(cframe){
+		name = fname;
+		setAttribute("name", fname);
+		id = fname;
+	}
+	(document.body||document.getElementsByTagName("body")[0]).appendChild(cframe);
+	window[fname] = cframe;
+	with(cframe.style){
+		position = "absolute";
+		left = top = "0px";
+		height = width = "1px";
+		visibility = "hidden";
+		/*
+		if(djConfig.isDebug){
+			position = "relative";
+			height = "300px";
+			width = "600px";
+			visibility = "visible";
+		}
+		*/
+	}
+
+	if(!r.ie){
+		dojo.io.setIFrameSrc(cframe, turi, true);
+		cframe.onload = new Function(onloadstr);
+	}
+	return cframe;
+}
+
+// thanks burstlib!
+dojo.io.iframeContentWindow = function(iframe_el) {
+	var win = iframe_el.contentWindow || // IE
+		dojo.io.iframeContentDocument(iframe_el).defaultView || // Moz, opera
+		// Moz. TODO: is this available when defaultView isn't?
+		dojo.io.iframeContentDocument(iframe_el).__parent__ || 
+		(iframe_el.name && document.frames[iframe_el.name]) || null;
+	return win;
+}
+
+dojo.io.iframeContentDocument = function(iframe_el){
+	var doc = iframe_el.contentDocument || // W3
+		(
+			(iframe_el.contentWindow)&&(iframe_el.contentWindow.document)
+		) ||  // IE
+		(
+			(iframe_el.name)&&(document.frames[iframe_el.name])&&
+			(document.frames[iframe_el.name].document)
+		) || null;
+	return doc;
+}
+
+dojo.io.IframeTransport = new function(){
+	var _this = this;
+	this.currentRequest = null;
+	this.requestQueue = [];
+	this.iframeName = "dojoIoIframe";
+
+	this.fireNextRequest = function(){
+		if((this.currentRequest)||(this.requestQueue.length == 0)){ return; }
+		// dojo.debug("fireNextRequest");
+		var cr = this.currentRequest = this.requestQueue.shift();
+		var fn = cr["formNode"];
+		if(fn){
+			if(cr["content"]){
+				// if we have things in content, we need to add them to the form
+				// before submission
+				for(var x in cr.content){
+					if(!fn[x]){
+						var tn;
+						if(dojo.render.html.ie){
+							tn = document.createElement("<input type='hidden' name='"+x+"' value='"+cr.content[x]+"'>");
+							fn.appendChild(tn);
+						}else{
+							tn = document.createElement("input");
+							fn.appendChild(tn);
+							tn.type = "hidden";
+							tn.name = x;
+							tn.value = cr.content[x];
+						}
+					}else{
+						fn[x].value = cr.content[x];
+					}
+				}
+			}
+			if(cr["url"]){
+				fn.setAttribute("action", cr.url);
+			}
+			if(!fn.getAttribute("method")){
+				fn.setAttribute("method", (cr["method"]) ? cr["method"] : "post");
+			}
+			fn.setAttribute("target", this.iframeName);
+			fn.target = this.iframeName;
+			fn.submit();
+		}else{
+			// otherwise we post a GET string by changing URL location for the
+			// iframe
+			var query = dojo.io.argsFromMap(this.currentRequest.content);
+			var tmpUrl = (cr.url.indexOf("?") > -1 ? "&" : "?") + query;
+			dojo.io.setIFrameSrc(this.iframe, tmpUrl, true);
+		}
+	}
+
+	this.canHandle = function(kwArgs){
+		return (
+			(
+				// FIXME: can we really handle text/plain and
+				// text/javascript requests?
+				dojo.lang.inArray(kwArgs["mimetype"], 
+				[	"text/plain", "text/html", 
+					"application/xml", "text/xml", 
+					"text/javascript", "text/json"])
+			)&&(
+				// make sur we really only get used in file upload cases	
+				(kwArgs["formNode"])&&(dojo.io.checkChildrenForFile(kwArgs["formNode"]))
+			)&&(
+				dojo.lang.inArray(kwArgs["method"].toLowerCase(), ["post", "get"])
+			)&&(
+				// never handle a sync request
+				!  ((kwArgs["sync"])&&(kwArgs["sync"] == true))
+			)
+		);
+	}
+
+	this.bind = function(kwArgs){
+		this.requestQueue.push(kwArgs);
+		this.fireNextRequest();
+		return;
+	}
+
+	this.setUpIframe = function(){
+
+		// NOTE: IE 5.0 and earlier Mozilla's don't support an onload event for
+		//       iframes. OTOH, we don't care.
+		this.iframe = dojo.io.createIFrame(this.iframeName, "dojo.io.IframeTransport.iframeOnload();");
+	}
+
+	this.iframeOnload = function(){
+		if(!_this.currentRequest){
+			_this.fireNextRequest();
+			return;
+		}
+		var ifr = _this.iframe;
+		var ifw = dojo.io.iframeContentWindow(ifr);
+		// handle successful returns
+		// FIXME: how do we determine success for iframes? Is there an equiv of
+		// the "status" property?
+		var value;
+		try{
+			var cmt = _this.currentRequest.mimetype;
+			if((cmt == "text/javascript")||(cmt == "text/json")){
+				// FIXME: not sure what to do here? try to pull some evalulable
+				// text from a textarea or cdata section? 
+				// how should we set up the contract for that?
+				var cd = dojo.io.iframeContentDocument(_this.iframe);
+				var js = cd.getElementsByTagName("textarea")[0].value;
+				if(cmt == "text/json") { js = "(" + js + ")"; }
+				value = dj_eval(js);
+			}else if((cmt == "application/xml")||(cmt == "text/xml")){
+				value = dojo.io.iframeContentDocument(_this.iframe);
+			}else{ // text/plain
+				value = ifw.innerHTML;
+			}
+			if(typeof _this.currentRequest.load == "function"){
+				_this.currentRequest.load("load", value, _this.currentRequest);
+			}
+		}catch(e){ 
+			// looks like we didn't get what we wanted!
+			var errObj = new dojo.io.Error("IframeTransport Error");
+			if(typeof _this.currentRequest["error"] == "function"){
+				_this.currentRequest.error("error", errObj, _this.currentRequest);
+			}
+		}
+		_this.currentRequest = null;
+		_this.fireNextRequest();
+	}
+
+	dojo.io.transports.addTransport("IframeTransport");
+}
+
+dojo.addOnLoad(function(){
+	dojo.io.IframeTransport.setUpIframe();
+});

Added: portals/jetspeed-2/trunk/applications/j2-admin/src/webapp/dojo/src/io/RepubsubIO.js
URL: http://svn.apache.org/viewcvs/portals/jetspeed-2/trunk/applications/j2-admin/src/webapp/dojo/src/io/RepubsubIO.js?rev=354516&view=auto
==============================================================================
--- portals/jetspeed-2/trunk/applications/j2-admin/src/webapp/dojo/src/io/RepubsubIO.js (added)
+++ portals/jetspeed-2/trunk/applications/j2-admin/src/webapp/dojo/src/io/RepubsubIO.js Tue Dec  6 11:29:56 2005
@@ -0,0 +1,514 @@
+dojo.require("dojo.event.Event");
+dojo.require("dojo.event.BrowserEvent");
+dojo.require("dojo.io.BrowserIO");
+
+dojo.provide("dojo.io.RepubsubIO");
+dojo.provide("dojo.io.repubsub");
+dojo.provide("dojo.io.repubsubTransport");
+
+dojo.io.repubsubTranport = new function(){
+	var rps = dojo.io.repubsub;
+	this.canHandle = function(kwArgs){
+		if((kwArgs["mimetype"] == "text/javascript")&&(kwArgs["method"] == "repubsub")){
+			return true;
+		}
+		return false;
+	}
+
+	this.bind = function(kwArgs){
+		if(!rps.isInitialized){
+			// open up our tunnel, queue up requests anyway
+			rps.init();
+		}
+		// FIXME: we need to turn this into a topic subscription
+		// var tgtURL = kwArgs.url+"?"+dojo.io.argsFromMap(kwArgs.content);
+		// sampleTransport.sendRequest(tgtURL, hdlrFunc);
+
+		// a normal "bind()" call in a request-response transport layer is
+		// something that (usually) encodes most of it's payload with the
+		// request. Multi-event systems like repubsub are a bit more complex,
+		// and repubsub in particular distinguishes the publish and subscribe
+		// portions of thep rocess with different method calls to handle each.
+		// Therefore, a "bind" in the sense of repubsub must first determine if
+		// we have an open subscription to a channel provided by the server,
+		// and then "publish" the request payload if there is any. We therefore
+		// must take care not to incorrectly or too agressively register or
+		// file event handlers which are provided with the kwArgs method.
+
+		// NOTE: we ONLY pay attention to those event handlers that are
+		// registered with the bind request that subscribes to the channel. If
+		// event handlers are provided with subsequent requests, we might in
+		// the future support some additive or replacement syntax, but for now
+		// they get dropped on the floor.
+
+		// NOTE: in this case, url MUST be the "topic" to which we
+		// subscribe/publish for this channel
+		if(!rps.topics[kwArgs.url]){
+			kwArgs.rpsLoad = function(evt){
+				kwArgs.load("load", evt);
+			}
+			rps.subscribe = function(kwArgs.url, kwArgs, "rpsLoad");
+		}
+
+		if(kwArgs["content"]){
+			// what we wanted to send
+			var cEvt = dojo.io.repubsubEvent.initFromProperties(kwArgs.content);
+			rps.publish(kwArgs.url, cEvt);
+		}
+	}
+
+	dojo.io.transports.addTransport("repubsubTranport");
+}
+
+dojo.io.repubsub = new function(){
+	this.initDoc = "init.html";
+	this.isInitialized = false;
+	this.subscriptionBacklog = [];
+	this.debug = true;
+	this.rcvNodeName = null;
+	this.sndNodeName = null;
+	this.rcvNode = null;
+	this.sndNode = null;
+	this.canRcv = false;
+	this.canSnd = false;
+	this.canLog = false;
+	this.sndTimer = null;
+	this.windowRef = window;
+	this.backlog = [];
+	this.tunnelInitCount = 0;
+	this.tunnelFrameKey = "tunnel_frame";
+	this.serverBaseURL = location.protocol+"//"+location.host+location.pathname;
+	this.logBacklog = [];
+	this.getRandStr = function(){
+		return Math.random().toString().substring(2, 10);
+	}
+	this.userid = "guest";
+	this.tunnelID = this.getRandStr();
+	this.attachPathList = [];
+	this.topics = []; // list of topics we have listeners to
+
+	// actually, now that I think about it a little bit more, it would sure be
+	// useful to parse out the <script> src attributes. We're looking for
+	// something with a "do_method=lib", since that's what would have included
+	// us in the first place (in the common case).
+	this.parseGetStr = function(){
+		var baseUrl = document.location.toString();
+		var params = baseUrl.split("?", 2);
+		if(params.length > 1){
+			var paramStr = params[1];
+			var pairs = paramStr.split("&");
+			var opts = [];
+			for(var x in pairs){
+				var sp = pairs[x].split("=");
+				// FIXME: is this eval dangerous?
+				try{
+					opts[sp[0]]=eval(sp[1]);
+				}catch(e){
+					opts[sp[0]]=sp[1];
+				}
+			}
+			return opts;
+		}else{
+			return [];
+		}
+	}
+
+	// parse URL params and use them as default vals
+	var getOpts = this.parseGetStr();
+	for(var x in getOpts){
+		// FIXME: should I be checking for undefined here before setting? Does
+		//        that buy me anything?
+		this[x] = getOpts[x];
+	}
+
+	if(!this["tunnelURI"]){
+		this.tunnelURI = [	"/who/", escape(this.userid), "/s/", 
+							this.getRandStr(), "/kn_journal"].join("");
+		// this.tunnelURI = this.absoluteTopicURI(this.tunnelURI);
+	}
+
+	/*
+	if (self.kn_tunnelID) kn.tunnelID = self.kn_tunnelID; // the server says
+	if (kn._argv.kn_tunnelID) kn.tunnelID = kn._argv.kn_tunnelID; // the url says
+	*/
+
+	// check the options object if it exists and use its properties as an
+	// over-ride
+	if(window["repubsubOpts"]||window["rpsOpts"]){
+		var optObj = window["repubsubOpts"]||window["rpsOpts"];
+		for(var x in optObj){
+			this[x] = optObj[x]; // copy the option object properties
+		}
+	}
+
+	// things that get called directly from our iframe to inform us of events
+	this.tunnelCloseCallback = function(){
+		// when we get this callback, we should immediately attempt to re-start
+		// our tunnel connection
+		dojo.io.setIFrameSrc(this.rcvNode, this.initDoc+"?callback=repubsub.rcvNodeReady&domain="+document.domain);
+	}
+
+	this.receiveEventFromTunnel = function(evt, srcWindow){
+		// we should never be getting events from windows we didn't create
+		// NOTE: events sourced from the local window are also supported for
+		// 		 debugging purposes
+
+		// any event object MUST have a an "elements" property
+		if(!evt["elements"]){
+			this.log("bailing! event received without elements!", "error");
+			return;
+		}
+
+		// if the event passes some minimal sanity tests, we need to attempt to
+		// dispatch it!
+
+		// first, it seems we have to munge the event object a bit
+		var e = {};
+		for(var i=0; i<evt.elements.length; i++){
+			var ee = evt.elements[i];
+			e[ee.name||ee.nameU] = (ee.value||ee.valueU);
+			// FIXME: need to enable this only in some extreme debugging mode!
+			this.log("[event]: "+(ee.name||ee.nameU)+": "+e[ee.name||ee.nameU]);
+		}
+
+		// NOTE: the previous version of this library put a bunch of code here
+		// to manage state that tried to make sure that we never, ever, lost
+		// any info about an event. If we unload RIGHT HERE, I don't think it's
+		// going to make a huge difference one way or another. Time will tell.
+
+		// and with THAT out of the way, dispatch it!
+		this.dispatch(e);
+
+		// TODO: remove the script block that created the event obj to save
+		// memory, etc.
+	}
+
+	this.widenDomain = function(domainStr){
+		// the purpose of this is to set the most liberal domain policy
+		// available
+		var cd = domainStr||document.domain;
+		if(cd.indexOf(".")==-1){ return; } // probably file:/// or localhost
+		var dps = cd.split(".");
+		if(dps.length<=2){ return; } // probably file:/// or an RFC 1918 address
+		dps = dps.slice(dps.length-2);
+		document.domain = dps.join(".");
+	}
+
+	// FIXME: parseCookie and setCookie should be methods that are more broadly
+	// available. Perhaps in htmlUtils?
+
+	this.parseCookie = function(){
+		var cs = document.cookie;
+		var keypairs = cs.split(";");
+		for(var x=0; x<keypairs.length; x++){
+			keypairs[x] = keypairs[x].split("=");
+			if(x!=keypairs.length-1){ cs+=";"; }
+		}
+		return keypairs;
+	}
+
+	this.setCookie = function(keypairs, clobber){
+		// NOTE: we want to only ever set session cookies, so never provide an
+		// 		 expires date
+		if((clobber)&&(clobber==true)){ document.cookie = ""; }
+		var cs = "";
+		for(var x=0; x<keypairs.length; x++){
+			cs += keypairs[x][0]+"="+keypairs[x][1];
+			if(x!=keypairs.length-1){ cs+=";"; }
+		}
+		document.cookie = cs;
+	}
+
+	// FIXME: need to replace w/ dojo.log.*
+	this.log = function(str, lvl){
+		if(!this.debug){ return; } // we of course only care if we're in debug mode
+		while(this.logBacklog.length>0){
+			if(!this.canLog){ break; }
+			var blo = this.logBacklog.shift();
+			this.writeLog("["+blo[0]+"]: "+blo[1], blo[2]);
+		}
+		this.writeLog(str, lvl);
+	}
+
+	this.writeLog = function(str, lvl){
+		dojo.debug(((new Date()).toLocaleTimeString())+": "+str);
+	}
+
+	this.init = function(){
+		this.widenDomain();
+		// this.findPeers();
+		this.openTunnel();
+		this.isInitialized = true;
+		// FIXME: this seems like entirely the wrong place to replay the backlog
+		while(this.subscriptionBacklog.length){
+			this.subscribe.apply(this, this.subscriptionBacklog.shift());
+		}
+	}
+
+	this.clobber = function(){
+		if(this.rcvNode){
+			this.setCookie( [
+					[this.tunnelFrameKey,"closed"],
+					["path","/"]
+				], false 
+			);
+		}
+	}
+
+	this.openTunnel = function(){
+		// We create two iframes here:
+
+		// one for getting data
+		this.rcvNodeName = "rcvIFrame_"+this.getRandStr();
+		// set cookie that can be used to find the receiving iframe
+		this.setCookie( [
+				[this.tunnelFrameKey,this.rcvNodeName],
+				["path","/"]
+			], false
+		);
+
+		this.rcvNode = dojo.io.createIFrame(this.rcvNodeName);
+		// FIXME: set the src attribute here to the initialization URL
+		dojo.io.setIFrameSrc(this.rcvNode, this.initDoc+"?callback=repubsub.rcvNodeReady&domain="+document.domain);
+
+		// the other for posting data in reply
+
+		this.sndNodeName = "sndIFrame_"+this.getRandStr();
+		this.sndNode = dojo.io.createIFrame(this.sndNodeName);
+		// FIXME: set the src attribute here to the initialization URL
+		dojo.io.setIFrameSrc(this.sndNode, this.initDoc+"?callback=repubsub.sndNodeReady&domain="+document.domain);
+
+	}
+
+	this.rcvNodeReady = function(){
+		// FIXME: why is this sequence number needed? Why isn't the UID gen
+		// 		  function enough?
+        var statusURI = [this.tunnelURI, '/kn_status/', this.getRandStr(), '_', 
+						 String(this.tunnelInitCount++)].join(""); 
+            // (kn._seqNum++); // FIXME: !!!!
+		// this.canRcv = true;
+		this.log("rcvNodeReady");
+		// FIXME: initialize receiver and request the base topic
+		// dojo.io.setIFrameSrc(this.rcvNode, this.serverBaseURL+"/kn?do_method=blank");
+		var initURIArr = [	this.serverBaseURL, "/kn?kn_from=", escape(this.tunnelURI),
+							"&kn_id=", escape(this.tunnelID), "&kn_status_from=", 
+							escape(statusURI)];
+		// FIXME: does the above really need a kn_response_flush? won't the
+		// 		  server already know? If not, what good is it anyway?
+		dojo.io.setIFrameSrc(this.rcvNode, initURIArr.join(""));
+
+		// setup a status path listener, but don't tell the server about it,
+		// since it already knows we're itnerested in our own tunnel status
+		this.subscribe(statusURI, this, "statusListener", true);
+
+		this.log(initURIArr.join(""));
+	}
+
+	this.sndNodeReady = function(){
+		this.canSnd = true;
+		this.log("sndNodeReady");
+		this.log(this.backlog.length);
+		// FIXME: handle any pent-up send commands
+		if(this.backlog.length > 0){
+			this.dequeueEvent();
+		}
+	}
+
+	this.statusListener = function(evt){
+		this.log("status listener called");
+		this.log(evt.status, "info");
+	}
+
+	// this handles local event propigation
+	this.dispatch = function(evt){
+		// figure out what topic it came from
+		if(evt["to"]||evt["kn_routed_from"]){
+			var rf = evt["to"]||evt["kn_routed_from"];
+			// split off the base server URL
+			var topic = rf.split(this.serverBaseURL, 2)[1];
+			if(!topic){
+				// FIXME: how do we recover when we don't get a sane "from"? Do
+				// we try to route to it anyway?
+				topic = rf;
+			}
+			this.log("[topic] "+topic);
+			if(topic.length>3){
+				if(topic.slice(0, 3)=="/kn"){
+					topic = topic.slice(3);
+				}
+			}
+			if(this.attachPathList[topic]){
+				this.attachPathList[topic](evt);
+			}
+		}
+	}
+
+	this.subscribe = function(	topic /* kn_from in the old terminilogy */, 
+								toObj, toFunc, dontTellServer){
+		if(!this.isInitialized){
+			this.subscriptionBacklog.push([topic, toObj, toFunc, dontTellServer]);
+			return;
+		}
+		if(!this.attachPathList[topic]){
+			this.attachPathList[topic] = function(){ return true; }
+			this.log("subscribing to: "+topic);
+			this.topics.push(topic);
+		}
+		var revt = new dojo.io.repubsubEvent(this.tunnelURI, topic, "route");
+		var rstr = [this.serverBaseURL+"/kn", revt.toGetString()].join("");
+		dojo.event.kwConnect({
+			once: true,
+			srcObj: this.attachPathList, 
+			srcFunc: topic, 
+			adviceObj: toObj, 
+			adviceFunc: toFunc
+		});
+		// NOTE: the above is a local mapping, if we're not the leader, we
+		// 		 should connect our mapping to the topic handler of the peer
+		// 		 leader, this ensures that not matter what happens to the
+		// 		 leader, we don't really loose our heads if/when the leader
+		// 		 goes away.
+		if(!this.rcvNode){ /* this should be an error! */ }
+		if(dontTellServer){
+			return;
+		}
+		this.log("sending subscription to: "+topic);
+		// create a subscription event object and give it all the props we need
+		// to updates on the specified topic
+
+		// FIXME: we should only enqueue if this is our first subscription!
+		this.sendTopicSubToServer(topic, rstr);
+	}
+
+	this.sendTopicSubToServer = function(topic, str){
+		if(!this.attachPathList[topic]["subscriptions"]){
+			this.enqueueEventStr(str);
+			this.attachPathList[topic].subscriptions = 0;
+		}
+		this.attachPathList[topic].subscriptions++;
+	}
+
+	this.unSubscribe = function(topic, toObj, toFunc){
+		// first, locally disconnect
+		dojo.event.kwDisconnect({
+			srcObj: this.attachPathList, 
+			srcFunc: topic, 
+			adviceObj: toObj, 
+			adviceFunc: toFunc
+		});
+		
+		// FIXME: figure out if there are any remaining listeners to the topic,
+		// 		  and if not, inform the server of our desire not to be
+		// 		  notified of updates to the topic
+	}
+
+	// the "publish" method is really a misnomer, since it really means "take
+	// this event and send it to the server". Note that the "dispatch" method
+	// handles local event promigulation, and therefore we emulate both sides
+	// of a real event router without having to swallow all of the complexity.
+	this.publish = function(topic, event){
+		var evt = dojo.io.repubsubEvent.initFromProperties(event);
+		// FIXME: need to make sure we have from and to set correctly
+		// 		  before we serialize and send off to the great blue
+		// 		  younder.
+		evt.to = topic;
+		// evt.from = this.tunnelURI;
+
+		var evtURLParts = [];
+		evtURLParts.push(this.serverBaseURL+"/kn");
+
+		// serialize the event to a string and then post it to the correct
+		// topic
+		evtURLParts.push(evt.toGetString());
+		this.enqueueEventStr(evtURLParts.join(""));
+	}
+
+	this.enqueueEventStr = function(evtStr){
+		this.log("enqueueEventStr");
+		this.backlog.push(evtStr);
+		this.dequeueEvent();
+	}
+
+	this.dequeueEvent = function(force){
+		this.log("dequeueEvent");
+		if(this.backlog.length <= 0){ return; }
+		if((this.canSnd)||(force)){
+			dojo.io.setIFrameSrc(this.sndNode, this.backlog.shift()+"&callback=repubsub.sndNodeReady");
+			this.canSnd = false;
+		}else{
+			this.log("sndNode not available yet!", "debug");
+		}
+	}
+}
+
+dojo.io.repubsubEvent = function(to, from, method, id, routeURI, payload, dispname, uid){
+	this.to = to;
+	this.from = from;
+	this.method = method||"route";
+	this.id = id||repubsub.getRandStr();
+	this.uri = routeURI;
+	this.displayname = dispname||repubsub.displayname;
+	this.userid = uid||repubsub.userid;
+	this.payload = payload||"";
+	this.flushChars = 4096;
+
+	this.initFromProperties = function(evt){
+		if(evt.constructor = dojo.io.repubsubEvent){ 
+			for(var x in evt){
+				this[x] = evt[x];
+			}
+		}else{
+			// we want to copy all the properties of the evt object, and transform
+			// those that are "stock" properties of dojo.io.repubsubEvent. All others should
+			// be copied as-is
+			for(var x in evt){
+				if(typeof this.forwardPropertiesMap[x] == "string"){
+					this[this.forwardPropertiesMap[x]] = evt[x];
+				}else{
+					this[x] = evt[x];
+				}
+			}
+		}
+	}
+
+	this.toGetString = function(noQmark){
+		var qs = [ ((noQmark) ? "" : "?") ];
+		for(var x=0; x<this.properties.length; x++){
+			var tp = this.properties[x];
+			if(this[tp[0]]){
+				qs.push(tp[1]+"="+encodeURIComponent(String(this[tp[0]])));
+			}
+			// FIXME: we need to be able to serialize non-stock properties!!!
+		}
+		return qs.join("&");
+	}
+
+}
+
+dojo.io.repubsubEvent.prototype.properties = [["from", "kn_from"], ["to", "kn_to"], 
+									["method", "do_method"], ["id", "kn_id"], 
+									["uri", "kn_uri"], 
+									["displayname", "kn_displayname"], 
+									["userid", "kn_userid"], 
+									["payload", "kn_payload"],
+									["flushChars", "kn_response_flush"],
+									["responseFormat", "kn_response_format"] ];
+
+// maps properties from their old names to their new names...
+dojo.io.repubsubEvent.prototype.forwardPropertiesMap = {};
+// ...and vice versa...
+dojo.io.repubsubEvent.prototype.reversePropertiesMap = {};
+
+// and we then populate them both from the properties list
+for(var x=0; x<dojo.io.repubsubEvent.prototype.properties.length; x++){
+	var tp = dojo.io.repubsubEvent.prototype.properties[x];
+	dojo.io.repubsubEvent.prototype.reversePropertiesMap[tp[0]] = tp[1];
+	dojo.io.repubsubEvent.prototype.forwardPropertiesMap[tp[1]] = tp[0];
+}
+// static version of initFromProperties, creates new event and object and
+// returns it after init
+dojo.io.repubsubEvent.initFromProperties = function(evt){
+	var eventObj = new dojo.io.repubsubEvent();
+	eventObj.initFromProperties(evt);
+	return eventObj;
+}

Added: portals/jetspeed-2/trunk/applications/j2-admin/src/webapp/dojo/src/io/RhinoIO.js
URL: http://svn.apache.org/viewcvs/portals/jetspeed-2/trunk/applications/j2-admin/src/webapp/dojo/src/io/RhinoIO.js?rev=354516&view=auto
==============================================================================
--- portals/jetspeed-2/trunk/applications/j2-admin/src/webapp/dojo/src/io/RhinoIO.js (added)
+++ portals/jetspeed-2/trunk/applications/j2-admin/src/webapp/dojo/src/io/RhinoIO.js Tue Dec  6 11:29:56 2005
@@ -0,0 +1,12 @@
+dojo.provide("dojo.io.RhinoIO");
+
+// TODO: this doesn't execute
+/*dojo.io.SyncHTTPRequest = function(){
+	dojo.io.SyncRequest.call(this);
+
+	this.send = function(URI){
+	}
+}
+
+dojo.inherits(dojo.io.SyncHTTPRequest, dojo.io.SyncRequest);
+*/

Added: portals/jetspeed-2/trunk/applications/j2-admin/src/webapp/dojo/src/io/__package__.js
URL: http://svn.apache.org/viewcvs/portals/jetspeed-2/trunk/applications/j2-admin/src/webapp/dojo/src/io/__package__.js?rev=354516&view=auto
==============================================================================
--- portals/jetspeed-2/trunk/applications/j2-admin/src/webapp/dojo/src/io/__package__.js (added)
+++ portals/jetspeed-2/trunk/applications/j2-admin/src/webapp/dojo/src/io/__package__.js Tue Dec  6 11:29:56 2005
@@ -0,0 +1,6 @@
+dojo.hostenv.conditionalLoadModule({
+	common: ["dojo.io", false, false],
+	rhino: ["dojo.io.RhinoIO", false, false],
+	browser: [["dojo.io.BrowserIO", false, false], ["dojo.io.cookie", false, false]]
+});
+dojo.hostenv.moduleLoaded("dojo.io.*");

Added: portals/jetspeed-2/trunk/applications/j2-admin/src/webapp/dojo/src/io/cookie.js
URL: http://svn.apache.org/viewcvs/portals/jetspeed-2/trunk/applications/j2-admin/src/webapp/dojo/src/io/cookie.js?rev=354516&view=auto
==============================================================================
--- portals/jetspeed-2/trunk/applications/j2-admin/src/webapp/dojo/src/io/cookie.js (added)
+++ portals/jetspeed-2/trunk/applications/j2-admin/src/webapp/dojo/src/io/cookie.js Tue Dec  6 11:29:56 2005
@@ -0,0 +1,89 @@
+dojo.provide("dojo.io.cookie");
+
+dojo.io.cookie.setCookie = function(name, value, days, path, domain, secure) {
+	var expires = -1;
+	if(typeof days == "number" && days >= 0) {
+		var d = new Date();
+		d.setTime(d.getTime()+(days*24*60*60*1000));
+		expires = d.toGMTString();
+	}
+	value = escape(value);
+	document.cookie = name + "=" + value + ";"
+		+ (expires != -1 ? " expires=" + expires + ";" : "")
+		+ (path ? "path=" + path : "")
+		+ (domain ? "; domain=" + domain : "")
+		+ (secure ? "; secure" : "");
+}
+
+dojo.io.cookie.set = dojo.io.cookie.setCookie;
+
+dojo.io.cookie.getCookie = function(name) {
+	var idx = document.cookie.indexOf(name+'=');
+	if(idx == -1) { return null; }
+	value = document.cookie.substring(idx+name.length+1);
+	var end = value.indexOf(';');
+	if(end == -1) { end = value.length; }
+	value = value.substring(0, end);
+	value = unescape(value);
+	return value;
+}
+
+dojo.io.cookie.get = dojo.io.cookie.getCookie;
+
+dojo.io.cookie.deleteCookie = function(name) {
+	dojo.io.cookie.setCookie(name, "-", 0);
+}
+
+dojo.io.cookie.setObjectCookie = function(name, obj, days, path, domain, secure, clearCurrent) {
+	if(arguments.length == 5) { clearCurrent = domain; } // for backwards compat
+	var pairs = [], cookie, value = "";
+	if(!clearCurrent) { cookie = dojo.io.cookie.getObjectCookie(name); }
+	if(days >= 0) {
+		if(!cookie) { cookie = {}; }
+		for(var prop in obj) {
+			if(prop == null) {
+				delete cookie[prop];
+			} else if(typeof obj[prop] == "string" || typeof obj[prop] == "number") {
+				cookie[prop] = obj[prop];
+			}
+		}
+		prop = null;
+		for(var prop in cookie) {
+			pairs.push(escape(prop) + "=" + escape(cookie[prop]));
+		}
+		value = pairs.join("&");
+	}
+	dojo.io.cookie.setCookie(name, value, days, path);
+}
+
+dojo.io.cookie.getObjectCookie = function(name) {
+	var values = null, cookie = dojo.io.cookie.getCookie(name);
+	if(cookie) {
+		values = {};
+		var pairs = cookie.split("&");
+		for(var i = 0; i < pairs.length; i++) {
+			var pair = pairs[i].split("=");
+			var value = pair[1];
+			if( isNaN(value) ) { value = unescape(pair[1]); }
+			values[ unescape(pair[0]) ] = value;
+		}
+	}
+	return values;
+}
+
+dojo.io.cookie.isSupported = function() {
+	if(typeof navigator.cookieEnabled != "boolean") {
+		dojo.io.cookie.setCookie("__TestingYourBrowserForCookieSupport__",
+			"CookiesAllowed", 90, null);
+		var cookieVal = dojo.io.cookie.getCookie("__TestingYourBrowserForCookieSupport__");
+		navigator.cookieEnabled = (cookieVal == "CookiesAllowed");
+		if(navigator.cookieEnabled) {
+			// FIXME: should we leave this around?
+			this.deleteCookie("__TestingYourBrowserForCookieSupport__");
+		}
+	}
+	return navigator.cookieEnabled;
+}
+
+// need to leave this in for backwards-compat from 0.1 for when it gets pulled in by dojo.io.*
+if(!dojo.io.cookies) { dojo.io.cookies = dojo.io.cookie; }

Added: portals/jetspeed-2/trunk/applications/j2-admin/src/webapp/dojo/src/io/cookies.js
URL: http://svn.apache.org/viewcvs/portals/jetspeed-2/trunk/applications/j2-admin/src/webapp/dojo/src/io/cookies.js?rev=354516&view=auto
==============================================================================
--- portals/jetspeed-2/trunk/applications/j2-admin/src/webapp/dojo/src/io/cookies.js (added)
+++ portals/jetspeed-2/trunk/applications/j2-admin/src/webapp/dojo/src/io/cookies.js Tue Dec  6 11:29:56 2005
@@ -0,0 +1,4 @@
+dj_deprecated("dojo.io.cookies has been replaced by dojo.io.cookie");
+dojo.require("dojo.io.cookie");
+if(!dojo.io.cookies) { dojo.io.cookies = dojo.io.cookie; }
+dojo.provide("dojo.io.cookies");

Added: portals/jetspeed-2/trunk/applications/j2-admin/src/webapp/dojo/src/jetspeed/JetspeedAjax.js
URL: http://svn.apache.org/viewcvs/portals/jetspeed-2/trunk/applications/j2-admin/src/webapp/dojo/src/jetspeed/JetspeedAjax.js?rev=354516&view=auto
==============================================================================
--- portals/jetspeed-2/trunk/applications/j2-admin/src/webapp/dojo/src/jetspeed/JetspeedAjax.js (added)
+++ portals/jetspeed-2/trunk/applications/j2-admin/src/webapp/dojo/src/jetspeed/JetspeedAjax.js Tue Dec  6 11:29:56 2005
@@ -0,0 +1,30 @@
+dojo.provide("dojo.jetspeed.JetspeedAjax");
+
+dojo.require("dojo.io.*");
+dojo.require("dojo.xml.Parse");
+
+dojo.jetspeed.getFragments = function(list)
+{
+	var kw = 
+	{
+		url: "http://localhost:8080/jetspeed/ajaxapi",
+		transport: "XMLHTTPTransport",
+		mimetype: "text/xml",
+		load: function(type, js, http) 
+		{
+//			dojo.debug("http:", http);
+//			dojo.debug("response:", http.responseText);
+//			dojo.debug("state:", http.readyState);
+
+            dom = http.responseXML.documentElement;
+            fragments = dom.getElementsByTagName('fragment');
+            for(i=0; i<fragments.length; i++)
+	        {          	        
+			  name = fragments[i].attributes[0].value;
+	          list.options[i] = new Option(name, name);
+ 	        }
+		}
+	};
+	dojo.io.bind(kw);
+
+}



---------------------------------------------------------------------
To unsubscribe, e-mail: jetspeed-dev-unsubscribe@portals.apache.org
For additional commands, e-mail: jetspeed-dev-help@portals.apache.org