text: /*
  	Copyright (c) 2004-2012, The Dojo Foundation All Rights Reserved.
  	Available via Academic Free License >= 2.1 OR the modified BSD license.
  	see: http://dojotoolkit.org/license for details
  */
  
  
  if(!dojo._hasResource["dojox.html.ellipsis"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  dojo._hasResource["dojox.html.ellipsis"] = true;
  dojo.provide("dojox.html.ellipsis");
  
  /*=====
  dojox.html.ellipsis = {
  	// summary: offers cross-browser support for text-overflow: ellipsis
  	//
  	// description: Add "dojoxEllipsis" on any node that you want to ellipsis-ize. In order to function properly,
  	//	the node with the dojoxEllipsis class set on it should be a child of a node with a defined width.
  	//	It should also be a block-level element (i.e. <div>) - it will not work on td elements.
  	//	NOTE: When using the dojoxEllipsis class within tables, the table needs to have the table-layout: fixed style
  }
  =====*/
  
  (function(d){
  	if(d.isMoz){ //TODO: feature detect text-overflow in computed style?
  		// The delay (in ms) to wait so that we don't keep querying when many
  		// changes happen at once - set config "dojoxFFEllipsisDelay" if you
  		// want a different value
  		var delay = 1;
  		if("dojoxFFEllipsisDelay" in d.config){
  			delay = Number(d.config.dojoxFFEllipsisDelay);
  			if(isNaN(delay)){
  				delay = 1;
  			}
  		}
  		try{
  			var createXULEllipsis = (function(){
  				// Create our stub XUL elements for cloning later
  				// NOTE: this no longer works as of FF 4.0:
  				// https://developer.mozilla.org/En/Firefox_4_for_developers#Remote_XUL_support_removed
  				var sNS = 'http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul';
  				var xml = document.createElementNS(sNS, 'window');
  				var label = document.createElementNS(sNS, 'description');
  				label.setAttribute('crop', 'end');
  				xml.appendChild(label);
  
  				return function(/* Node */ n){
  					// Summary:
  					//		Given a node, it creates the XUL and sets its
  					//		content so that it will have an ellipsis
  					var x = xml.cloneNode(true);
  					x.firstChild.setAttribute('value', n.textContent);
  					n.innerHTML = '';
  					n.appendChild(x);
  				};
  			})();
  		}catch(e){}
  		
  		// Create our iframe elements for cloning later
  		var create = d.create;
  		var dd = d.doc;
  		var dp = d.place;
  		var iFrame = create("iframe", {className: "dojoxEllipsisIFrame",
  					src: "javascript:'<html><head><script>if(\"loadFirebugConsole\" in window){window.loadFirebugConsole();}</script></head><body></body></html>'"});
  		var rollRange = function(/* W3C Range */ r, /* int? */ cnt){
  			// Summary:
  			//		Rolls the given range back one character from the end
  			//
  			//	r: W3C Range
  			//		The range to roll back
  			//	cnt: int?
  			//		An optional number of times to roll back (defaults 1)
  			if(r.collapsed){
  				// Do nothing - we are already collapsed
  				return;
  			}
  			if(cnt > 0){
  				do{
  					rollRange(r);
  					cnt--;
  				}while(cnt);
  				return;
  			}
  			if(r.endContainer.nodeType == 3 && r.endOffset > 0){
  				r.setEnd(r.endContainer, r.endOffset - 1);
  			}else if(r.endContainer.nodeType == 3){
  				r.setEndBefore(r.endContainer);
  				rollRange(r);
  				return;
  			}else if(r.endOffset && r.endContainer.childNodes.length >= r.endOffset){
  				var nCont = r.endContainer.childNodes[r.endOffset - 1];
  				if(nCont.nodeType == 3){
  					r.setEnd(nCont, nCont.length - 1);
  				}else if(nCont.childNodes.length){
  					r.setEnd(nCont, nCont.childNodes.length);
  					rollRange(r);
  					return;
  				}else{
  					r.setEndBefore(nCont);
  					rollRange(r);
  					return;
  				}
  			}else{
  				r.setEndBefore(r.endContainer);
  				rollRange(r);
  				return;
  			}
  		};
  		var createIFrameEllipsis = function(/* Node */ n){
  			// Summary:
  			//		Given a node, it creates an iframe and and ellipsis div and
  			//		sets up the connections so that they will work correctly.
  			//		This function is used when createXULEllipsis is not able
  			//		to be used (because there is markup within the node) - it's
  			//		a bit slower, but does the trick
  			var c = create("div", {className: "dojoxEllipsisContainer"});
  			var e = create("div", {className: "dojoxEllipsisShown", style: {display: "none"}});
  			n.parentNode.replaceChild(c, n);
  			c.appendChild(n);
  			c.appendChild(e);
  			var i = iFrame.cloneNode(true);
  			var ns = n.style;
  			var es = e.style;
  			var ranges;
  			var resizeNode = function(){
  				ns.display = "";
  				es.display = "none";
  				if(n.scrollWidth <= n.offsetWidth){ return; }
  				var r = dd.createRange();
  				r.selectNodeContents(n);
  				ns.display = "none";
  				es.display = "";
  				var done = false;
  				do{
  					var numRolls = 1;
  					dp(r.cloneContents(), e, "only");
  					var sw = e.scrollWidth, ow = e.offsetWidth;
  					done = (sw <= ow);
  					var pct = (1 - ((ow * 1) / sw));
  					if(pct > 0){
  						numRolls = Math.max(Math.round(e.textContent.length * pct) - 1, 1);
  					}
  					rollRange(r, numRolls);
  				}while(!r.collapsed && !done);
  			};
  			i.onload = function(){
  				i.contentWindow.onresize = resizeNode;
  				resizeNode();
  			};
  			c.appendChild(i);
  		};
  
  		// Function for updating the ellipsis
  		var hc = d.hasClass;
  		var doc = d.doc;
  		var s, fn, opt;
  		if(doc.querySelectorAll){
  			s = doc;
  			fn = "querySelectorAll";
  			opt = ".dojoxEllipsis";
  		}else if(doc.getElementsByClassName){
  			s = doc;
  			fn = "getElementsByClassName";
  			opt = "dojoxEllipsis";
  		}else{
  			s = d;
  			fn = "query";
  			opt = ".dojoxEllipsis";
  		}
  		fx = function(){
  			d.forEach(s[fn].apply(s, [opt]), function(n){
  				if(!n || n._djx_ellipsis_done){ return; }
  				n._djx_ellipsis_done = true;
  				if(createXULEllipsis && n.textContent == n.innerHTML && !hc(n, "dojoxEllipsisSelectable")){
  					// We can do the faster XUL version, instead of calculating
  					createXULEllipsis(n);
  				}else{
  					createIFrameEllipsis(n);
  				}
  			});
  		};
  		
  		d.addOnLoad(function(){
  			// Apply our initial stuff
  			var t = null;
  			var c = null;
  			var connFx = function(){
  				if(c){
  					// disconnect us - so we don't fire anymore
  					d.disconnect(c);
  					c = null;
  				}
  				if(t){ clearTimeout(t); }
  				t = setTimeout(function(){
  					t = null;
  					fx();
  					// Connect to the modified function so that we can catch
  					// our next change
  					c = d.connect(d.body(), "DOMSubtreeModified", connFx);
  				}, delay);
  			};
  			connFx();
  		});
  	}
  })(dojo);
  
  }
  