/*
	Copyright (c) 2004-2006, The Dojo Foundation
	All Rights Reserved.

	Licensed under the Academic Free License version 2.1 or above OR the
	modified BSD license. For more information on Dojo licensing, see:

		http://dojotoolkit.org/community/licensing.shtml
*/

 /* -*- tab-width: 4 -*- */
dojo.provide("dojo.widget.RichText");

dojo.require("dojo.widget.*");
dojo.require("dojo.html.*");
dojo.require("dojo.html.layout");
dojo.require("dojo.html.selection");
dojo.require("dojo.event.*");
dojo.require("dojo.string.extras");
dojo.require("dojo.uri.Uri");
dojo.require("dojo.Deferred");

// used to save content
if(dojo.hostenv.post_load_){
	(function(){
		var savetextarea = dojo.doc().createElement('textarea');
		savetextarea.id = "dojo.widget.RichText.savedContent";
		savetextarea.style = "display:none;position:absolute;top:-100px;left:-100px;height:3px;width:3px;overflow:hidden;";
		dojo.body().appendChild(savetextarea);
	})();
}else{
	//dojo.body() is not available before onLoad is fired
	try {
		dojo.doc().write('<textarea id="dojo.widget.RichText.savedContent" ' +
			'style="display:none;position:absolute;top:-100px;left:-100px;height:3px;width:3px;overflow:hidden;"></textarea>');
	}catch(e){ }
}

dojo.widget.defineWidget(
	"dojo.widget.RichText",
	dojo.widget.HtmlWidget,
	function(){
		// summary:
		//		dojo.widget.RichText is the core of the WYSIWYG editor in dojo, which
		//		provides the basic editing features. It also encapsulates the differences
		//		of different js engines for various browsers

		// contentPreFilters: Array
		//		pre content filter function register array
		this.contentPreFilters = [];

		// contentPostFilters: Array
		//		post content filter function register array
		this.contentPostFilters = [];

		// contentDomPreFilters: Array
		//		pre content dom filter function register array
		this.contentDomPreFilters = [];

		// contentDomPostFilters: Array
		//		post content dom filter function register array
		this.contentDomPostFilters = [];

		// editingAreaStyleSheets: Array
		//		array to store all the stylesheets applied to the editing area
		this.editingAreaStyleSheets=[];

		if(dojo.render.html.moz){
			this.contentPreFilters.push(this._fixContentForMoz);
		}

		this._keyHandlers = {};

		if(dojo.Deferred){
			this.onLoadDeferred = new dojo.Deferred();
		}
	},
	{
		// inheritWidth: Boolean
		//		whether to inherit the parent's width or simply use 100%
		inheritWidth: false,

		// focusOnLoad: Boolean
		//		whether focusing into this instance of richtext when page onload
		focusOnLoad: false,

		// saveName: String
		//		If a save name is specified the content is saved and restored when the user
		//		leave this page can come back, or if the editor is not properly closed after
		//		editing has started.
		saveName: "",

		// styleSheets: String
		//		semicolon (";") separated list of css files for the editing area
		styleSheets: "",

		// _content: String
		//		temporary content storage
		_content: "",

		// height: String
		//		set height to fix the editor at a specific height, with scrolling
		height: "",

		// minHeight: String
		//		The minimum height that the editor should have
		minHeight: "1em",

		// isClosed: Boolean
		isClosed: true,

		// isLoaded: Boolean
		isLoaded: false,

		// useActiveX: Boolean
		//		whether to use the active-x object in IE
		useActiveX: false,

		// relativeImageUrls: Boolean
		//		whether to use relative URLs for images - if this is enabled
		//		images will be given absolute URLs when inside the editor but
		//		will be changed to use relative URLs (to the current page) on save
		relativeImageUrls: false,

		// _SEPARATOR: String
		//		used to concat contents from multiple textareas into a single string
		_SEPARATOR: "@@**%%__RICHTEXTBOUNDRY__%%**@@",

		// onLoadDeferred: dojo.Deferred
		//		deferred that can be used to connect to the onLoad function. This
		//		will only be set if dojo.Deferred is required
		onLoadDeferred: null,

	/* Init
	 *******/

		fillInTemplate: function(){
			// summary: see dojo.widget.DomWidget
			dojo.event.topic.publish("dojo.widget.RichText::init", this);
			this.open();


			// backwards compatibility, needs to be removed
			dojo.event.connect(this, "onKeyPressed", this, "afterKeyPress");
			dojo.event.connect(this, "onKeyPress", this, "keyPress");
			dojo.event.connect(this, "onKeyDown", this, "keyDown");
			dojo.event.connect(this, "onKeyUp", this, "keyUp");

			this.setupDefaultShortcuts();
		},

		setupDefaultShortcuts: function(){
			// summary: add some default key handlers
			// description:
			// 		Overwrite this to setup your own handlers. The default
			// 		implementation does not use Editor2 commands, but directly
			//		executes the builtin commands within the underlying browser
			//		support.
			var ctrl = this.KEY_CTRL;
			var exec = function (cmd, arg) {
				return arguments.length == 1 ? function () { this.execCommand(cmd); } :
					function () { this.execCommand(cmd, arg); }
			}
			this.addKeyHandler("b", ctrl, exec("bold"));
			this.addKeyHandler("i", ctrl, exec("italic"));
			this.addKeyHandler("u", ctrl, exec("underline"));
			this.addKeyHandler("a", ctrl, exec("selectall"));
			this.addKeyHandler("s", ctrl, function () { this.save(true); });

			this.addKeyHandler("1", ctrl, exec("formatblock", "h1"));
			this.addKeyHandler("2", ctrl, exec("formatblock", "h2"));
			this.addKeyHandler("3", ctrl, exec("formatblock", "h3"));
			this.addKeyHandler("4", ctrl, exec("formatblock", "h4"));

			this.addKeyHandler("\\", ctrl, exec("insertunorderedlist"));
			if(!dojo.render.html.ie){
				this.addKeyHandler("Z", ctrl, exec("redo"));
			}
		},

		// events: Array
		//		 events which should be connected to the underlying editing area
		events: ["onBlur", "onFocus", "onKeyPress", "onKeyDown", "onKeyUp", "onClick"],

		/**
		 * Transforms the node referenced in this.domNode into a rich text editing
		 * node. This can result in the creation and replacement with an <iframe> if
		 * designMode is used, an <object> and active-x component if inside of IE or
		 * a reguler element if contentEditable is available.
		 */
		open: function (/*DomNode, optional*/element) {
			// summary:
			//		Transforms the node referenced in this.domNode into a rich text editing
			//		node. This can result in the creation and replacement with an <iframe> if
			//		designMode is used, an <object> and active-x component if inside of IE or
			//		a reguler element if contentEditable is available.

			if(this.onLoadDeferred.fired >= 0){
				this.onLoadDeferred = new dojo.Deferred();
			}

			var h = dojo.render.html;
			if (!this.isClosed) { this.close(); }
			dojo.event.topic.publish("dojo.widget.RichText::open", this);

			this._content = "";
			if((arguments.length == 1)&&(element["nodeName"])){ this.domNode = element; } // else unchanged

			if(	(this.domNode["nodeName"])&&
				(this.domNode.nodeName.toLowerCase() == "textarea")){
				this.textarea = this.domNode;
				var html = dojo.string.trim(this.textarea.value);
				this.domNode = dojo.doc().createElement("div");
				dojo.html.copyStyle(this.domNode, this.textarea);
				var tmpFunc = dojo.lang.hitch(this, function(){
					//some browsers refuse to submit display=none textarea, so
					//move the textarea out of screen instead
					with(this.textarea.style){
						display = "block";
						position = "absolute";
						left = top = "-1000px";

						if(h.ie){ //nasty IE bug: abnormal formatting if overflow is not hidden
							this.__overflow = overflow;
							overflow = "hidden";
						}
					}
				});
				if(h.ie){
					setTimeout(tmpFunc, 10);
				}else{
					tmpFunc();
				}
				if(!h.safari){
					// FIXME: VERY STRANGE safari 2.0.4 behavior here caused by
					// moving the textarea. Often crashed the browser!!! Seems
					// fixed on webkit nightlies.
					dojo.html.insertBefore(this.domNode, this.textarea);
				}
				// this.domNode.innerHTML = html;

				if(this.textarea.form){
					dojo.event.connect('before', this.textarea.form, "onsubmit",
						// FIXME: should we be calling close() here instead?
						dojo.lang.hitch(this, function(){
							this.textarea.value = this.getEditorContent();
						})
					);
				}

				// dojo plucks our original domNode from the document so we need
				// to go back and put ourselves back in
				var editor = this;
				dojo.event.connect(this, "postCreate", function (){
					dojo.html.insertAfter(editor.textarea, editor.domNode);
				});
			}else{
				var html = this._preFilterContent(dojo.string.trim(this.domNode.innerHTML));
			}
			if(html == ""){ html = "&nbsp;"; }
			var content = dojo.html.getContentBox(this.domNode);
			this._oldHeight = content.height;
			this._oldWidth = content.width;

			this._firstChildContributingMargin = this._getContributingMargin(this.domNode, "top");
			this._lastChildContributingMargin = this._getContributingMargin(this.domNode, "bottom");

			this.savedContent = this.domNode.innerHTML;
			this.domNode.innerHTML = '';

			this.editingArea = dojo.doc().createElement("div");
			this.domNode.appendChild(this.editingArea);

			// If we're a list item we have to put in a blank line to force the
			// bullet to nicely align at the top of text
			if(	(this.domNode["nodeName"])&&
				(this.domNode.nodeName == "LI")){
				this.domNode.innerHTML = " <br>";
			}

			if(this.saveName != ""){
				var saveTextarea = dojo.doc().getElementById("dojo.widget.RichText.savedContent");
				if (saveTextarea.value != "") {
					var datas = saveTextarea.value.split(this._SEPARATOR);
					for (var i = 0; i < datas.length; i++) {
						var data = datas[i].split(":");
						if (data[0] == this.saveName) {
							html = data[1];
							datas.splice(i, 1);
							break;
						}
					}
				}
				dojo.event.connect("before", window, "onunload", this, "_saveContent");
				// dojo.event.connect(window, "onunload", this, "_saveContent");
			}

			if(h.ie70 && this.useActiveX){
				dojo.debug("activeX in ie70 is not currently supported, useActiveX is ignored for now.");
				this.useActiveX = false;
			}
			// Safari's selections go all out of whack if we do it inline,
			// so for now IE is our only hero
			//if (typeof document.body.contentEditable != "undefined") {
			if(this.useActiveX && h.ie){ // active-x
				var self = this;
				//if call _drawObject directly here, textarea replacement
				//won't work: no content is shown. However, add a delay
				//can workaround this. No clue why.
				setTimeout(function(){self._drawObject(html);}, 0);
			}else if(h.ie || this._safariIsLeopard() || h.opera){ // contentEditable, easy
				this.iframe = dojo.doc().createElement( 'iframe' ) ;
				this.iframe.src = 'javascript:void(0)';
				this.editorObject = this.iframe;
				with(this.iframe.style){
					border = '0';
					width = "100%";
				}
				this.iframe.frameBorder = 0;
				this.editingArea.appendChild(this.iframe)
				this.window = this.iframe.contentWindow;
				this.document = this.window.document;
				this.document.open();
				this.document.write("<html><head><style>body{margin:0;padding:0;border:0;overflow:hidden;}</style></head><body><div></div></body></html>");
				this.document.close();
				this.editNode = this.document.body.firstChild;//document.createElement("div");
				this.editNode.contentEditable = true;
				with (this.iframe.style) {
					if(h.ie70){
						if(this.height){
							height = this.height;
						}
						if(this.minHeight){
							minHeight = this.minHeight;
						}
					}else{
						height = this.height ? this.height : this.minHeight;
					}
				}

				// FIXME: setting contentEditable on switches this element to
				// IE's hasLayout mode, triggering weird margin collapsing
				// behavior. It's particularly bad if the element you're editing
				// contains childnodes that don't have margin: defined in local
				// css rules. It would be nice if it was possible to hack around
				// this. Sadly _firstChildContributingMargin and
				// _lastChildContributingMargin don't work on IE unless all
				// elements have margins set in CSS :-(

				//if the normal way fails, we try the hard way to get the list
				//do not use _cacheLocalBlockFormatNames here, as it will trigger security warning in IE7
				//in the array below, ul can not come directly after ol, otherwise the queryCommandValue returns Normal for it
				var formats = ['p', 'pre', 'address', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ol', 'div', 'ul'];
				var localhtml = "";
				for(var i in formats){
					if(formats[i].charAt(1) != 'l'){
						localhtml += "<"+formats[i]+"><span>content</span></"+formats[i]+">";
					}else{
						localhtml += "<"+formats[i]+"><li>content</li></"+formats[i]+">";
					}
				}
				//queryCommandValue returns empty if we hide editNode, so move it out of screen temporary
				with(this.editNode.style){
					position = "absolute";
					left = "-2000px";
					top = "-2000px";
				}
				this.editNode.innerHTML = localhtml;
				var node = this.editNode.firstChild;
				while(node){
					dojo.withGlobal(this.window, "selectElement", dojo.html.selection, [node.firstChild]);
					var nativename = node.tagName.toLowerCase();
					this._local2NativeFormatNames[nativename] = this.queryCommandValue("formatblock");
//						dojo.debug([nativename,this._local2NativeFormatNames[nativename]]);
					this._native2LocalFormatNames[this._local2NativeFormatNames[nativename]] = nativename;
					node = node.nextSibling;
				}
				with(this.editNode.style){
					position = "";
					left = "";
					top = "";
				}

				this.editNode.innerHTML = html;
				if(this.height){ this.document.body.style.overflowY="scroll"; }

				dojo.lang.forEach(this.events, function(e){
					dojo.event.connect(this.editNode, e.toLowerCase(), this, e);
				}, this);

				this.onLoad();
			} else { // designMode in iframe
				this._drawIframe(html);
				this.editorObject = this.iframe;
			}

			// TODO: this is a guess at the default line-height, kinda works
			if (this.domNode.nodeName == "LI") { this.domNode.lastChild.style.marginTop = "-1.2em"; }
			dojo.html.addClass(this.domNode, "RichTextEditable");

			this.isClosed = false;
		},

		_hasCollapseableMargin: function(/*DomNode*/element, /*String*/side) {
			// summary:
			//		check if an element has padding or borders on the given side
			//		which would prevent it from collapsing margins
			if (dojo.html.getPixelValue(element,
										 'border-'+side+'-width',
										 false)) {
				return false;
			} else if (dojo.html.getPixelValue(element,
												'padding-'+side,
												false)) {
				return false;
			} else {
				return true;
			}
		},

		_getContributingMargin:	function(/*DomNode*/element, /*String*/topOrBottom) {
			// summary:
			//		calculate how much margin this element and its first or last
			//		child are contributing to the total margin between this element
			//		and the adjacent node. CSS border collapsing makes this
			//		necessary.

			if (topOrBottom == "top") {
				var siblingAttr = "previousSibling";
				var childSiblingAttr = "nextSibling";
				var childAttr = "firstChild";
				var marginProp = "margin-top";
				var siblingMarginProp = "margin-bottom";
			} else {
				var siblingAttr = "nextSibling";
				var childSiblingAttr = "previousSibling";
				var childAttr = "lastChild";
				var marginProp = "margin-bottom";
				var siblingMarginProp = "margin-top";
			}

			var elementMargin = dojo.html.getPixelValue(element, marginProp, false);

			function isSignificantNode(element) {
				// see if an node is significant in the current context
				// for calulating margins
				return !(element.nodeType==3 && dojo.string.isBlank(element.data))
					&& dojo.html.getStyle(element, "display") != "none"
					&& !dojo.html.isPositionAbsolute(element);
			}

			// walk throuh first/last children to find total collapsed margin size
			var childMargin = 0;
			var child = element[childAttr];
			while (child) {
				// skip over insignificant elements (whitespace, etc)
				while ((!isSignificantNode(child)) && child[childSiblingAttr]) {
					child = child[childSiblingAttr];
				}

				childMargin = Math.max(childMargin, dojo.html.getPixelValue(child, marginProp, false));
				// stop if we hit a bordered/padded element
				if (!this._hasCollapseableMargin(child, topOrBottom)) break;
				child = child[childAttr];
			}

			// if this element has a border, return full child margin immediately
			// as there won't be any margin collapsing
			if (!this._hasCollapseableMargin(element, topOrBottom)){ return parseInt(childMargin); }

			// find margin supplied by nearest sibling
			var contextMargin = 0;
			var sibling = element[siblingAttr];
			while (sibling) {
				if (isSignificantNode(sibling)) {
					contextMargin = dojo.html.getPixelValue(sibling,
															 siblingMarginProp,
															 false);
					break;
				}
				sibling = sibling[siblingAttr];
			}
			if (!sibling) { // no sibling, look at parent's margin instead
				contextMargin = dojo.html.getPixelValue(element.parentNode,
												marginProp, false);
			}

			if (childMargin > elementMargin) {
				return parseInt(Math.max((childMargin-elementMargin)-contextMargin, 0));
			} else {
				return 0;
			}

		},

		_drawIframe: function (/*String*/html){
			// summary:
			//		Draws an iFrame using the existing one if one exists.
			//		Used by Mozilla, Safari, and Opera

			// detect firefox < 1.5, which has some iframe loading issues
			var oldMoz = Boolean(dojo.render.html.moz && (
									typeof window.XML == 'undefined'))

			if(!this.iframe){
				var currentDomain = (new dojo.uri.Uri(dojo.doc().location)).host;
				this.iframe = dojo.doc().createElement("iframe");
				// dojo.body().appendChild(this.iframe);
				with(this.iframe){
					style.border = "none";
					style.lineHeight = "0"; // squash line height
					style.verticalAlign = "bottom";
					scrolling = this.height ? "auto" : "no";
				}
			}
			// opera likes this to be outside the with block
			this.iframe.src = dojo.uri.dojoUri("src/widget/templates/richtextframe.html") + ((dojo.doc().domain != currentDomain) ? ("#"+dojo.doc().domain) : "");
			this.iframe.width = this.inheritWidth ? this._oldWidth : "100%";
			if(this.height){
				this.iframe.style.height = this.height;
			}else{
				var height = this._oldHeight;
				if(this._hasCollapseableMargin(this.domNode, 'top')){
					height += this._firstChildContributingMargin;
				}
				if(this._hasCollapseableMargin(this.domNode, 'bottom')){
					height += this._lastChildContributingMargin;
				}
				this.iframe.height = height;
			}

			var tmpContent = dojo.doc().createElement('div');
			tmpContent.innerHTML = html;
			//append tmpContent to under the current domNode so that the margin
			//calculation below is correct
			this.editingArea.appendChild(tmpContent);

			// make relative image urls absolute
			if(this.relativeImageUrls){
				var imgs = tmpContent.getElementsByTagName('img');
				for(var i=0; i<imgs.length; i++){
					imgs[i].src = (new dojo.uri.Uri(dojo.global().location, imgs[i].src)).toString();
				}
				html = tmpContent.innerHTML;
			}

			// fix margins on tmpContent
			var firstChild = dojo.html.firstElement(tmpContent);
			var lastChild = dojo.html.lastElement(tmpContent);
			if(firstChild){
				firstChild.style.marginTop = this._firstChildContributingMargin+"px";
			}
			if(lastChild){
				lastChild.style.marginBottom = this._lastChildContributingMargin+"px";
			}
			//do we want to show the content before the editing area finish loading here?
			//if external style sheets are used for the editing area, the appearance now
			//and after loading of the editing area won't be the same (and padding/margin
			//calculation above may not be accurate)
//			tmpContent.style.display = "none";
			this.editingArea.appendChild(this.iframe);
			if(dojo.render.html.safari){
				this.iframe.src = this.iframe.src;
			}

			var _iframeInitialized = false;

			// now we wait for onload. Janky hack!
			var ifrFunc = dojo.lang.hitch(this, function(){
				if(!_iframeInitialized){
					_iframeInitialized = true;
				}else{ return; }
				if(!this.editNode){
					if(this.iframe.contentWindow){
						this.window = this.iframe.contentWindow;
						this.document = this.iframe.contentWindow.document
					}else if(this.iframe.contentDocument){
						// for opera
						this.window = this.iframe.contentDocument.window;
						this.document = this.iframe.contentDocument;
					}

					// curry the getStyle function
					var getStyle = (function (domNode) { return function (style) {
						return dojo.html.getStyle(domNode, style);
					}; })(this.domNode);

					var font =
						getStyle('font-weight') + " " +
						getStyle('font-size') + " " +
						getStyle('font-family');

					// line height is tricky - applying a units value will mess things up.
					// if we can't get a non-units value, bail out.
					var lineHeight = "1.0";
					var lineHeightStyle = dojo.html.getUnitValue(this.domNode, 'line-height');
					if (lineHeightStyle.value && lineHeightStyle.units=="") {
						lineHeight = lineHeightStyle.value;
					}

					dojo.html.insertCssText(
						'body,html{background:transparent;padding:0;margin:0;}' +
						// TODO: left positioning will case contents to disappear out of view
						//       if it gets too wide for the visible area
						'body{top:0;left:0;right:0;' +
						(((this.height)||(dojo.render.html.opera)) ? '' : 'position:fixed;') +
						'font:' + font + ';' +
						'min-height:' + this.minHeight + ';' +
						'line-height:' + lineHeight + '}' +
						'p{margin: 1em 0 !important;}' +
						'body > *:first-child{padding-top:0 !important;margin-top:' + this._firstChildContributingMargin + 'px !important;}' + // FIXME: test firstChild nodeType
						'body > *:last-child{padding-bottom:0 !important;margin-bottom:' + this._lastChildContributingMargin + 'px !important;}' +
						'li > ul:-moz-first-node, li > ol:-moz-first-node{padding-top:1.2em;}\n' +
						'li{min-height:1.2em;}' +
						//'    p,ul,li { padding-top: 0; padding-bottom: 0; margin-top:0; margin-bottom: 0; }\n' +
						'', this.document);

					dojo.html.removeNode(tmpContent);
					this.document.body.innerHTML = html;
					if(oldMoz||dojo.render.html.safari){
						this.document.designMode = "on";
					}
					this.onLoad();
				}else{
					dojo.html.removeNode(tmpContent);
					this.editNode.innerHTML = html;
					this.onDisplayChanged();
				}
			});

			if(this.editNode){
				ifrFunc(); // iframe already exists, just set content
			}else if(dojo.render.html.moz){
				// FIXME: if we put this on a delay, we get a height of 20px.
				// Otherwise we get the correctly specified minHeight value.
				this.iframe.onload = function(){
					setTimeout(ifrFunc, 250);
				}
			}else{ // new mozillas, opera, safari
				this.iframe.onload = ifrFunc;
			}
		},

		_applyEditingAreaStyleSheets: function(){
			// summary:
			//		apply the specified css files in styleSheets
			var files = [];
			if(this.styleSheets){
				files = this.styleSheets.split(';');
				this.styleSheets = '';
			}

			//empty this.editingAreaStyleSheets here, as it will be filled in addStyleSheet
			files = files.concat(this.editingAreaStyleSheets);
			this.editingAreaStyleSheets = [];

			if(files.length>0){
				for(var i=0;i<files.length;i++){
					var url = files[i];
					if(url){
						this.addStyleSheet(dojo.uri.dojoUri(url));
	 				}
	 			}
			}
		},

		addStyleSheet: function(/*dojo.uri.Uri*/uri) {
			// summary:
			//		add an external stylesheet for the editing area
			// uri:	a dojo.uri.Uri pointing to the url of the external css file
			var url=uri.toString();
			if(dojo.lang.find(this.editingAreaStyleSheets, url) > -1){
				dojo.debug("dojo.widget.RichText.addStyleSheet: Style sheet "+url+" is already applied to the editing area!");
				return;
			}

			//if uri is relative, then convert it to absolute so that it can be resolved correctly in iframe
			if(url.charAt(0) == '.' || (url.charAt(0) != '/' && !uri.host)){
				url = (new dojo.uri.Uri(dojo.global().location, url)).toString();
			}

			this.editingAreaStyleSheets.push(url);
			if(this.document.createStyleSheet){ //IE
				this.document.createStyleSheet(url);
			}else{ //other browser
				var head = this.document.getElementsByTagName("head")[0];
				var stylesheet = this.document.createElement("link");
				with(stylesheet){
					rel="stylesheet";
					type="text/css";
					href=url;
				}
				head.appendChild(stylesheet);
			}
		},

		removeStyleSheet: function (/*dojo.uri.Uri*/uri) {
			// summary:
			//		remove an external stylesheet for the editing area
			var url=uri.toString();
			//if uri is relative, then convert it to absolute so that it can be resolved correctly in iframe
			if(url.charAt(0) == '.' || (url.charAt(0) != '/' && !uri.host)){
				url = (new dojo.uri.Uri(dojo.global().location, url)).toString();
			}
			var index = dojo.lang.find(this.editingAreaStyleSheets, url);
			if(index == -1){
				dojo.debug("dojo.widget.RichText.removeStyleSheet: Style sheet "+url+" is not applied to the editing area so it can not be removed!");
				return;
			}
			delete this.editingAreaStyleSheets[index];

			var links = this.document.getElementsByTagName("link");
			for(var i=0;i<links.length;i++){
				if(links[i].href == url){
					if(dojo.render.html.ie){//we need to empty the href first, to get IE to remove the rendered styles
						links[i].href="";
					}
					dojo.html.removeNode(links[i]);
					break;
				}
			}
		},

		_drawObject: function (/*String*/html) {
			// summary:
			//		Draws an active x object, used by IE
			this.object = dojo.html.createExternalElement(dojo.doc(), "object");

			with (this.object) {
				classid = "clsid:2D360201-FFF5-11D1-8D03-00A0C959BC0A";
				width = this.inheritWidth ? this._oldWidth : "100%";
				style.height = this.height ? this.height : (this._oldHeight+"px");
				Scrollbars = this.height ? true : false;
				Appearance = this._activeX.appearance.flat;
			}
			this.editorObject = this.object;
			this.editingArea.appendChild(this.object);

			this.object.attachEvent("DocumentComplete", dojo.lang.hitch(this, "onLoad"));
			//DisplayChanged is fired too often even no change is made, so we ignore it
			//and call onDisplayChanged manually in execCommand instead
//			this.object.attachEvent("DisplayChanged", dojo.lang.hitch(this, "onDisplayChanged"));

			dojo.lang.forEach(this.events, function(e){
				this.object.attachEvent(e.toLowerCase(), dojo.lang.hitch(this, e));
			}, this);

			this.object.DocumentHTML = '<!doctype HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">' +
				'<html><title></title>' +
				'<style type="text/css">' +
				'    body,html { padding: 0; margin: 0; }' + //font: ' + font + '; }' +
				(this.height ? '' : '    body,  { overflow: hidden; }') +
				'</style>' +
				//'<base href="' + dojo.global().location + '">' +
				'<body><div>' + html + '<div></body></html>';

			this._cacheLocalBlockFormatNames();
		},

		//static cache variables shared among all instance of this class
		_local2NativeFormatNames: {},
		_native2LocalFormatNames: {},
		//in IE, names for blockformat is locale dependent, so we cache the values here
		//we use activeX to obtain the list, if success or the names are already cached,
		//return true
		_cacheLocalBlockFormatNames: function(){
			// summary:
			//		in IE, names for blockformat is locale dependent, so we cache the values here
			//		we use activeX to obtain the list, if success or the names are already cached,
			//		return true
			if(!this._native2LocalFormatNames['p']){
				var obj = this.object;
				var error = false;
				if(!obj){
					//create obj temporarily
					try{
						obj = dojo.html.createExternalElement(dojo.doc(), "object");
						obj.classid = "clsid:2D360201-FFF5-11D1-8D03-00A0C959BC0A";
						dojo.body().appendChild(obj);
						obj.DocumentHTML = "<html><head></head><body></body></html>";
					}catch(e){ error = true; }
				}
				try{
					var oNamesParm = new ActiveXObject("DEGetBlockFmtNamesParam.DEGetBlockFmtNamesParam");
					obj.ExecCommand(this._activeX.command['getblockformatnames'], 0, oNamesParm);
					var vbNamesArray = new VBArray(oNamesParm.Names);
					var localFormats = vbNamesArray.toArray();
					var nativeFormats = ['p', 'pre', 'address', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ol', 'ul', '', '', '','','div'];
					for(var i=0;i<nativeFormats.length;++i){
						if(nativeFormats[i].length>0){
							this._local2NativeFormatNames[localFormats[i]] = nativeFormats[i];
							this._native2LocalFormatNames[nativeFormats[i]] = localFormats[i];
						}
					}
				}catch(e){ error = true; }
				if(obj && !this.object){
					//delete the temporary obj
					dojo.body().removeChild(obj);
				}
			}
			return !error;
		},
	/* Event handlers
	 *****************/

		_isResized: function(){ return false; },

		onLoad: function(e){
			// summary: handler after the content of the document finishes loading
			this.isLoaded = true;
			if (this.object){
				this.document = this.object.DOM;
				this.window = this.document.parentWindow;
				this.editNode = this.document.body.firstChild;
				this.editingArea.style.height = this.height ? this.height : this.minHeight;
				if(!this.height){
					this.connect(this, "onDisplayChanged", "_updateHeight");
				}
				//pretend the object as an iframe, so that the context menu for the
				//editor can be placed correctly when shown
				this.window._frameElement = this.object;
			}else if (this.iframe && !dojo.render.html.ie){
				this.editNode = this.document.body;
				if(!this.height){
					this.connect(this, "onDisplayChanged", "_updateHeight");
				}

				try { // sanity check for Mozilla
					this.document.execCommand("useCSS", false, true); // old moz call
					this.document.execCommand("styleWithCSS", false, false); // new moz call
					//this.document.execCommand("insertBrOnReturn", false, false); // new moz call
				}catch(e2){ }

				if (dojo.render.html.safari) {
					/*
					this.iframe.style.visiblity = "visible";
					this.iframe.style.border = "1px solid black";
					this.editNode.style.visiblity = "visible";
					this.editNode.style.border = "1px solid black";
					*/
					// this.onDisplayChanged();
					this.connect(this.editNode, "onblur", "onBlur");
					this.connect(this.editNode, "onfocus", "onFocus");
					this.connect(this.editNode, "onclick", "onFocus");

					this.interval = setInterval(dojo.lang.hitch(this, "onDisplayChanged"), 750);
					// dojo.raise("onload");
					// dojo.debug(this.editNode.parentNode.parentNode.parentNode.nodeName);
				} else if (dojo.render.html.mozilla || dojo.render.html.opera) {
					var doc = this.document;
					var addListener = dojo.event.browser.addListener;
					var self = this;
					dojo.lang.forEach(this.events, function(e){
						var l = addListener(self.document, e.substr(2).toLowerCase(), dojo.lang.hitch(self, e));
						if(e=="onBlur"){
							// We need to unhook the blur event listener on close as we
							// can encounter a garunteed crash in FF if another event is
							// also fired
							var unBlur = { unBlur: function(e){
									dojo.event.browser.removeListener(doc, "blur", l);
							} };
							dojo.event.connect("before", self, "close", unBlur, "unBlur");
						}
					});
				}
				// FIXME: when scrollbars appear/disappear this needs to be fired
			}else if(dojo.render.html.ie){
				// IE contentEditable
				if(!this.height){
					this.connect(this, "onDisplayChanged", "_updateHeight");
				}
				this.editNode.style.zoom = 1.0;
			}

			this._applyEditingAreaStyleSheets();

			if(this.focusOnLoad){
				this.focus();
			}
			this.onDisplayChanged(e);
			if(this.onLoadDeferred){
				this.onLoadDeferred.callback(true);
			}
		},

		onKeyDown: function(e){
			// summary: Fired on keydown
			if((!e)&&(this.object)){
				e = dojo.event.browser.fixEvent(this.window.event);
			}
			// dojo.debug("onkeydown:", e.keyCode);
			// we need this event at the moment to get the events from control keys
			// such as the backspace. It might be possible to add this to Dojo, so that
			// keyPress events can be emulated by the keyDown and keyUp detection.
			if((dojo.render.html.ie)&&(e.keyCode == e.KEY_TAB)){
				e.preventDefault();
				e.stopPropagation();
				// FIXME: this is a poor-man's indent/outdent. It would be
				// better if it added 4 "&nbsp;" chars in an undoable way.
				// Unfortuantly pasteHTML does not prove to be undoable
				this.execCommand((e.shiftKey ? "outdent" : "indent"));
			}else if(dojo.render.html.ie){
				if((65 <= e.keyCode)&&(e.keyCode <= 90)){
					e.charCode = e.keyCode;
					this.onKeyPress(e);
				}
				// dojo.debug(e.ctrlKey);
				// dojo.debug(e.keyCode);
				// dojo.debug(e.charCode);
				// this.onKeyPress(e);
			}
		},

		onKeyUp: function(e){
			// summary: Fired on keyup
			return;
		},

		KEY_CTRL: 1,

		onKeyPress: function(e){
			// summary: Fired on keypress
			if((!e)&&(this.object)){
				e = dojo.event.browser.fixEvent(this.window.event);
			}
			// handle the various key events

			var modifiers = e.ctrlKey ? this.KEY_CTRL : 0;

			if (this._keyHandlers[e.key]) {
				// dojo.debug("char:", e.key);
				var handlers = this._keyHandlers[e.key], i = 0, handler;
				while (handler = handlers[i++]) {
					if (modifiers == handler.modifiers) {
						e.preventDefault();
						handler.handler.call(this);
						break;
					}
				}
			}

			// function call after the character has been inserted
			dojo.lang.setTimeout(this, this.onKeyPressed, 1, e);
		},

		addKeyHandler: function (/*String*/key, /*Int*/modifiers, /*Function*/handler) {
			// summary: add a handler for a keyboard shortcut
			if (!(this._keyHandlers[key] instanceof Array)) { this._keyHandlers[key] = []; }
			this._keyHandlers[key].push({
				modifiers: modifiers || 0,
				handler: handler
			});
		},

		onKeyPressed: function (e) {
			// summary:
			//		Fired after a keypress event has occured and it's action taken. This
		 	//		is useful if action needs to be taken after text operations have finished

			// Mozilla adds a single <p> with an embedded <br> when you hit enter once:
			//   <p><br>\n</p>
			// when you hit enter again it adds another <br> inside your enter
			//   <p><br>\n<br>\n</p>
			// and if you hit enter again it splits the <br>s over 2 <p>s
			//   <p><br>\n</p>\n<p><br>\n</p>
			// now this assumes that <p>s have double the line-height of <br>s to work
			// and so we need to remove the <p>s to ensure the position of the cursor
			// changes from the users perspective when they hit enter, as the second two
			// html snippets render the same when margins are set to 0.

			// TODO: doesn't really work; is this really needed?
			//if (dojo.render.html.moz) {
			//	for (var i = 0; i < this.document.getElementsByTagName("p").length; i++) {
			//		var p = this.document.getElementsByTagName("p")[i];
			//		if (p.innerHTML.match(/^<br>\s$/m)) {
			//			while (p.hasChildNodes()) { p.parentNode.insertBefore(p.firstChild, p); }
			//			p.parentNode.removeChild(p);
			//		}
			//	}
			//}
			this.onDisplayChanged(/*e*/); // can't pass in e
		},

		onClick: function(e){ this.onDisplayChanged(e); },
		onBlur: function(e){ },
		_initialFocus: true,
		onFocus: function(e){
			// summary: Fired on focus
			if( (dojo.render.html.mozilla)&&(this._initialFocus) ){
				this._initialFocus = false;
				if(dojo.string.trim(this.editNode.innerHTML) == "&nbsp;"){
					this.placeCursorAtStart();
//					this.execCommand("selectall");
//					this.window.getSelection().collapseToStart();
				}
			}
			/*
			// FIXME: attempted (but ultimately unworkable) solution for #2066
			if(dojo.render.html.safari){
				var sel = this.window.getSelection();
				dojo.debug(dojo.dom.isDescendantOf(sel.focusNode, this.document.body));

				var isLastNode = (sel.focusNode == this.document.body.lastChild);
				if(!isLastNode){ return; }
				var isText = (sel.focusNode.nodeType == 3);
				if(!isText){ return; }
				var isLastChar = (sel.focusOffset == sel.focusNode.nodeValue.length);
				if(!isLastChar){ return; }
				dojo.debug(sel.focusOffset, sel.focusNode.nodeValue.length);
				if(isLastNode && isText && isLastChar){
					this.document.body.appendChild(this.document.createTextNode(" "));
					this.document.body.appendChild(this.document.createElement("br"));
					this.document.body.appendChild(this.document.createElement("p"));
					this.document.body.appendChild(this.document.createElement("p"));
					sel.collapse(sel.focusNode, sel.focusOffset-1);
					sel.collapse(sel.focusNode, sel.focusOffset+1);
				}
			}
			*/
		},

		blur: function () {
			// summary: remove focus from this instance
			if(this.iframe) { this.window.blur(); }
			else if(this.object) { this.document.body.blur(); }
			else if(this.editNode) { this.editNode.blur(); }
		},

		focus: function () {
			// summary: move focus to this instance
			if(this.iframe && !dojo.render.html.ie) { this.window.focus(); }
			else if(this.object) { this.document.focus(); }
			// editNode may be hidden in display:none div, lets just punt in this case
			else if(this.editNode && this.editNode.focus) { this.editNode.focus(); }
			else{
				dojo.debug("Have no idea how to focus into the editor!");
			}
		},

		/** this event will be fired everytime the display context changes and the
		 result needs to be reflected in the UI */
		onDisplayChanged: function (e){ },


	/* Formatting commands
	 **********************/

		// Object: IE's Active X codes: see http://www.computerbytesman.com/js/activex/dhtmledit.htm
		_activeX: {
			command: {
				bold: 5000,
				italic: 5023,
				underline: 5048,

				justifycenter: 5024,
				justifyleft: 5025,
				justifyright: 5026,

				cut: 5003,
				copy: 5002,
				paste: 5032,
				"delete": 5004,

				undo: 5049,
				redo: 5033,

				removeformat: 5034,
				selectall: 5035,
				unlink: 5050,

				indent: 5018,
				outdent: 5031,

				insertorderedlist: 5030,
				insertunorderedlist: 5051,

				// table commands
				inserttable: 5022,
				insertcell: 5019,
				insertcol: 5020,
				insertrow: 5021,
				deletecells: 5005,
				deletecols: 5006,
				deleterows: 5007,
				mergecells: 5029,
				splitcell: 5047,

				// the command need mapping, they don't translate directly
				// to the contentEditable commands
				setblockformat: 5043,
				getblockformat: 5011,
				getblockformatnames: 5012,
				setfontname: 5044,
				getfontname: 5013,
				setfontsize: 5045,
				getfontsize: 5014,
				setbackcolor: 5042,
				getbackcolor: 5010,
				setforecolor: 5046,
				getforecolor: 5015,

				findtext: 5008,
				font: 5009,
				hyperlink: 5016,
				image: 5017,

				lockelement: 5027,
				makeabsolute: 5028,
				sendbackward: 5036,
				bringforward: 5037,
				sendbelowtext: 5038,
				bringabovetext: 5039,
				sendtoback: 5040,
				bringtofront: 5041,

				properties: 5052
			},

			ui: {
				"default": 0,
				prompt: 1,
				noprompt: 2
			},

			status: {
				notsupported: 0,
				disabled: 1,
				enabled: 3,
				latched: 7,
				ninched: 11
			},

			appearance: {
				flat: 0,
				inset: 1
			},

			state: {
				unchecked: 0,
				checked: 1,
				gray: 2
			}
		},

		_normalizeCommand: function (/*String*/cmd){
			// summary:
			//		Used as the advice function by dojo.event.connect to map our
		 	//		normalized set of commands to those supported by the target
		 	//		browser
			var drh = dojo.render.html;

			var command = cmd.toLowerCase();
			if(command == "formatblock"){
				if(drh.safari){ command = "heading"; }
			}else if(this.object){
				switch(command){
					case "createlink":
						command = "hyperlink";
						break;
					case "insertimage":
						command = "image";
						break;
				}
			}else if(command == "hilitecolor" && !drh.mozilla){
				command = "backcolor";
			}

			return command;
		},

		_safariIsLeopard: function(){
			var gt420 = false;
			if(dojo.render.html.safari){
				var tmp = dojo.render.html.UA.split("AppleWebKit/")[1];
				var ver = parseFloat(tmp.split(" ")[0]);
				if(ver >= 420){ gt420 = true; }
			}
			return gt420;
		},

		queryCommandAvailable: function (/*String*/command) {
			// summary:
			//		Tests whether a command is supported by the host. Clients SHOULD check
			//		whether a command is supported before attempting to use it, behaviour
			//		for unsupported commands is undefined.
			// command: The command to test for
			var ie = 1;
			var mozilla = 1 << 1;
			var safari = 1 << 2;
			var opera = 1 << 3;
			var safari420 = 1 << 4;

			var gt420 = this._safariIsLeopard();

			function isSupportedBy (browsers) {
				return {
					ie: Boolean(browsers & ie),
					mozilla: Boolean(browsers & mozilla),
					safari: Boolean(browsers & safari),
					safari420: Boolean(browsers & safari420),
					opera: Boolean(browsers & opera)
				}
			}

			var supportedBy = null;

			switch (command.toLowerCase()) {
				case "bold": case "italic": case "underline":
				case "subscript": case "superscript":
				case "fontname": case "fontsize":
				case "forecolor": case "hilitecolor":
				case "justifycenter": case "justifyfull": case "justifyleft":
				case "justifyright": case "delete": case "selectall":
					supportedBy = isSupportedBy(mozilla | ie | safari | opera);
					break;

				case "createlink": case "unlink": case "removeformat":
				case "inserthorizontalrule": case "insertimage":
				case "insertorderedlist": case "insertunorderedlist":
				case "indent": case "outdent": case "formatblock":
				case "inserthtml": case "undo": case "redo": case "strikethrough":
					supportedBy = isSupportedBy(mozilla | ie | opera | safari420);
					break;

				case "blockdirltr": case "blockdirrtl":
				case "dirltr": case "dirrtl":
				case "inlinedirltr": case "inlinedirrtl":
					supportedBy = isSupportedBy(ie);
					break;
				case "cut": case "copy": case "paste":
					supportedBy = isSupportedBy( ie | mozilla | safari420);
					break;

				case "inserttable":
					supportedBy = isSupportedBy(mozilla | (this.object ? ie : 0));
					break;

				case "insertcell": case "insertcol": case "insertrow":
				case "deletecells": case "deletecols": case "deleterows":
				case "mergecells": case "splitcell":
					supportedBy = isSupportedBy(this.object ? ie : 0);
					break;

				default: return false;
			}

			return (dojo.render.html.ie && supportedBy.ie) ||
				(dojo.render.html.mozilla && supportedBy.mozilla) ||
				(dojo.render.html.safari && supportedBy.safari) ||
				(gt420 && supportedBy.safari420) ||
				(dojo.render.html.opera && supportedBy.opera);  // Boolean return true if the command is supported, false otherwise
		},

		execCommand: function (/*String*/command, argument){
			// summary: Executes a command in the Rich Text area
			// command: The command to execute
			// argument: An optional argument to the command
			var returnValue;

			//focus() is required for IE (none-activeX mode) to work
			//In addition, focus() makes sure after the execution of
			//the command, the editor receives the focus as expected
			this.focus();

			command = this._normalizeCommand(command);
			if (argument != undefined) {
				if(command == "heading") { throw new Error("unimplemented"); }
				else if(command == "formatblock"){
					if(this.object){ //IE activeX mode
						argument = this._native2LocalFormatNames[argument];
					}
					else if(dojo.render.html.ie){ argument = '<'+argument+'>'; }
				}
			}
			if(this.object){
				switch (command) {
					case "hilitecolor":
						command = "setbackcolor";
						break;
					case "forecolor":
					case "backcolor":
					case "fontsize":
					case "fontname":
						command = "set" + command;
						break;
					case "formatblock":
						command = "setblockformat";
				}

				if(command == "strikethrough"){
					command = "inserthtml";
					var range = this.document.selection.createRange();
					if(!range.htmlText){
						return;
					}
					argument=range.htmlText.strike();
				}else if(command == "inserthorizontalrule"){
					command = "inserthtml";
					argument="<hr>";
				}

				if(command == "inserthtml"){
					var range = this.document.selection.createRange();
					if(this.document.selection.type.toUpperCase() == "CONTROL"){
						//if selection is controlrange, no pasteHTML is available,
						//we replace the outerHTML directly
						for(var i=0;i<range.length;i++){
							range.item(i).outerHTML = argument;
						}
					}else{
						// on IE, we can use the pasteHTML method of the textRange object
						// to get an undo-able innerHTML modification
						range.pasteHTML(argument);
						range.select();
					}
					returnValue = true;
				}else if(arguments.length == 1){
					returnValue = this.object.ExecCommand(this._activeX.command[command],
						this._activeX.ui.noprompt);
				}else{
					returnValue = this.object.ExecCommand(this._activeX.command[command],
						this._activeX.ui.noprompt, argument);
				}
			}else if(command == "inserthtml"){
				if(dojo.render.html.ie){
					//dojo.debug("inserthtml breaks the undo stack when not using the ActiveX version of the control!");
					var insertRange = this.document.selection.createRange();
					insertRange.pasteHTML(argument);
					insertRange.select();
					//insertRange.collapse(true);
					return true;
				}else{
					return this.document.execCommand(command, false, argument);
				}
			/* */
			// fix up unlink in Mozilla to unlink the link and not just the selection
			}else if((command == "unlink")&&
				(this.queryCommandEnabled("unlink"))&&
				(dojo.render.html.mozilla)){
				// grab selection
				// Mozilla gets upset if we just store the range so we have to
				// get the basic properties and recreate to save the selection
				var selection = this.window.getSelection();
				var selectionRange = selection.getRangeAt(0);
				var selectionStartContainer = selectionRange.startContainer;
				var selectionStartOffset = selectionRange.startOffset;
				var selectionEndContainer = selectionRange.endContainer;
				var selectionEndOffset = selectionRange.endOffset;

				// select our link and unlink
				var a = dojo.withGlobal(this.window, "getAncestorElement", dojo.html.selection, ['a']);
				dojo.withGlobal(this.window, "selectElement", dojo.html.selection, [a]);

				returnValue = this.document.execCommand("unlink", false, null);

				// restore original selection
				var selectionRange = this.document.createRange();
				selectionRange.setStart(selectionStartContainer, selectionStartOffset);
				selectionRange.setEnd(selectionEndContainer, selectionEndOffset);
				selection.removeAllRanges();
				selection.addRange(selectionRange);

				return returnValue;
			}else if((command == "hilitecolor")&&(dojo.render.html.mozilla)){
				// mozilla doesn't support hilitecolor properly when useCSS is
				// set to false (bugzilla #279330)

				this.document.execCommand("useCSS", false, false);
				returnValue = this.document.execCommand(command, false, argument);
				this.document.execCommand("useCSS", false, true);

			}else if((dojo.render.html.ie)&&( (command == "backcolor")||(command == "forecolor") )){
				// Tested under IE 6 XP2, no problem here, comment out
				// IE weirdly collapses ranges when we exec these commands, so prevent it
//				var tr = this.document.selection.createRange();
				argument = arguments.length > 1 ? argument : null;
				returnValue = this.document.execCommand(command, false, argument);

				// timeout is workaround for weird IE behavior were the text
				// selection gets correctly re-created, but subsequent input
				// apparently isn't bound to it
//				setTimeout(function(){tr.select();}, 1);
			}else{
				// dojo.debug("command:", command, "arg:", argument);

				argument = arguments.length > 1 ? argument : null;
//				if(dojo.render.html.moz){
//					this.document = this.iframe.contentWindow.document
//				}

				if(argument || command!="createlink") {
					returnValue = this.document.execCommand(command, false, argument);
				}
			}

			this.onDisplayChanged();
			return returnValue;
		},

		queryCommandEnabled: function(/*String*/command){
			// summary: check whether a command is enabled or not
			command = this._normalizeCommand(command);
			if(this.object){
				switch (command) {
					case "hilitecolor":
						command = "setbackcolor";
						break;
					case "forecolor":
					case "backcolor":
					case "fontsize":
					case "fontname":
						command = "set" + command;
						break;
					case "formatblock":
						command = "setblockformat";
						break;
					//below are not natively supported commands, we fake them
					case "strikethrough":
						command = "bold"; //whenever bold is enabled, strikethrough should be so as well
						break;
					case "inserthorizontalrule":
						return true;
				}

				if(typeof this._activeX.command[command] == "undefined"){ return false; }
				var status = this.object.QueryStatus(this._activeX.command[command]);
				return ((status != this._activeX.status.notsupported)&&
					(status != this._activeX.status.disabled));
			}else{
				if(dojo.render.html.mozilla){
					if(command == "unlink"){ // mozilla returns true always
						return dojo.withGlobal(this.window, "hasAncestorElement", dojo.html.selection, ['a']);
					} else if (command == "inserttable") {
						return true;
					}
				}

				// return this.document.queryCommandEnabled(command);
				var elem = (dojo.render.html.ie) ? this.document.selection.createRange() : this.document;
				return elem.queryCommandEnabled(command);
			}
		},

		queryCommandState: function(command){
			// summary: check the state of a given command
			command = this._normalizeCommand(command);
			if(this.object){
				if(command == "forecolor"){
					command = "setforecolor";
				}else if(command == "backcolor"){
					command = "setbackcolor";
				}else if(command == "strikethrough"){
					//check whether we are under a <strike>
					return dojo.withGlobal(this.window, "hasAncestorElement", dojo.html.selection, ['strike']);
				}else if(command == "inserthorizontalrule"){
					return false;
				}

				if(typeof this._activeX.command[command] == "undefined"){ return null; }
				var status = this.object.QueryStatus(this._activeX.command[command]);
				return ((status == this._activeX.status.latched)||
					(status == this._activeX.status.ninched));
			}else{
				return this.document.queryCommandState(command);
			}
		},

		queryCommandValue: function (command) {
			// summary: check the value of a given command
			command = this._normalizeCommand(command);
			if (this.object) {
				switch (command) {
					case "forecolor":
					case "backcolor":
					case "fontsize":
					case "fontname":
						command = "get" + command;
						return this.object.execCommand(
							this._activeX.command[command],
							this._activeX.ui.noprompt);
					case "formatblock":
						var retvalue = this.object.execCommand(
							this._activeX.command["getblockformat"],
							this._activeX.ui.noprompt);
						if(retvalue){
							return this._local2NativeFormatNames[retvalue];
						}
				}
			} else {
				if(dojo.render.html.ie && command == "formatblock"){
					return this._local2NativeFormatNames[this.document.queryCommandValue(command)] || this.document.queryCommandValue(command);
				}
				return this.document.queryCommandValue(command);
			}
		},


	/* Misc.
	 ********/

		placeCursorAtStart: function(){
			// summary:
			//		place the cursor at the start of the editing area
			this.focus();
			//see comments in placeCursorAtEnd
			if(dojo.render.html.moz && this.editNode.firstChild &&
				this.editNode.firstChild.nodeType != dojo.dom.TEXT_NODE){
				dojo.withGlobal(this.window, "selectElementChildren", dojo.html.selection, [this.editNode.firstChild]);
			}else{
				dojo.withGlobal(this.window, "selectElementChildren", dojo.html.selection, [this.editNode]);
			}
			dojo.withGlobal(this.window, "collapse", dojo.html.selection, [true]);
		},

		placeCursorAtEnd: function(){
			// summary:
			//		place the cursor at the end of the editing area
			this.focus();
			//In mozilla, if last child is not a text node, we have to use selectElementChildren on this.editNode.lastChild
			//otherwise the cursor would be placed at the end of the closing tag of this.editNode.lastChild
			if(dojo.render.html.moz && this.editNode.lastChild &&
				this.editNode.lastChild.nodeType != dojo.dom.TEXT_NODE){
				dojo.withGlobal(this.window, "selectElementChildren", dojo.html.selection, [this.editNode.lastChild]);
			}else{
				dojo.withGlobal(this.window, "selectElementChildren", dojo.html.selection, [this.editNode]);
			}
			dojo.withGlobal(this.window, "collapse", dojo.html.selection, [false]);
		},

		replaceEditorContent: function(/*String*/html){
			// summary:
			//		this function set the content while trying to maintain the undo stack
			html = this._preFilterContent(html);
			if(this.isClosed){
				this.domNode.innerHTML = html;
			}else if(this.window && this.window.getSelection && !dojo.render.html.moz){ // Safari
				// look ma! it's a totally f'd browser!
				this.editNode.innerHTML = html;
			}else if((this.window && this.window.getSelection) || (this.document && this.document.selection)){ // Moz/IE
				this.execCommand("selectall");
				if(dojo.render.html.moz && !html){ html = "&nbsp;" }
				this.execCommand("inserthtml", html);
			}
		},

		_preFilterContent: function(/*String*/html){
			// summary:
			//		filter the input before setting the content of the editing area
			var ec = html;
			dojo.lang.forEach(this.contentPreFilters, function(ef){
				ec = ef(ec);
			});
			if(this.contentDomPreFilters.length>0){
				var dom = dojo.doc().createElement('div');
				dom.style.display = "none";
				dojo.body().appendChild(dom);
				dom.innerHTML = ec;
				dojo.lang.forEach(this.contentDomPreFilters, function(ef){
					dom = ef(dom);
				});
				ec = dom.innerHTML;
				dojo.body().removeChild(dom);
			}
			return ec;
		},
		_postFilterContent: function(/*String*/html){
			// summary:
			//		filter the output after getting the content of the editing area
			var ec = html;
			if(this.contentDomPostFilters.length>0){
				var dom = this.document.createElement('div');
				dom.innerHTML = ec;
				dojo.lang.forEach(this.contentDomPostFilters, function(ef){
					dom = ef(dom);
				});
				ec = dom.innerHTML;
			}
			dojo.lang.forEach(this.contentPostFilters, function(ef){
				ec = ef(ec);
			});
			return ec;
		},

		//Int: stored last time height
		_lastHeight: 0,

		_updateHeight: function(){
			// summary:
			//		Updates the height of the editor area to fit the contents.
			if(!this.isLoaded){ return; }
			if(this.height){ return; }

			var height = dojo.html.getBorderBox(this.editNode).height;
			//height maybe zero in some cases even though the content is not empty,
			//we try the height of body instead
			if(!height){
				height = dojo.html.getBorderBox(this.document.body).height;
			}
			if(height == 0){
				dojo.debug("Can not figure out the height of the editing area!");
				return; //prevent setting height to 0
			}
			this._lastHeight = height;
			this.editorObject.style.height = this._lastHeight + "px";
			this.window.scrollTo(0, 0);
		},

		_saveContent: function(e){
			// summary:
			//		Saves the content in an onunload event if the editor has not been closed
			var saveTextarea = dojo.doc().getElementById("dojo.widget.RichText.savedContent");
			saveTextarea.value += this._SEPARATOR + this.saveName + ":" + this.getEditorContent();
		},

		getEditorContent: function(){
			// summary:
			//		return the current content of the editing area (post filters are applied)
			var ec = "";
			try{
				ec = (this._content.length > 0) ? this._content : this.editNode.innerHTML;
				if(dojo.string.trim(ec) == "&nbsp;"){ ec = ""; }
			}catch(e){ /* squelch */ }

			if(dojo.render.html.ie && !this.object){
				//removing appended <P>&nbsp;</P> for IE in none-activeX mode
				var re = new RegExp("(?:<p>&nbsp;</p>[\n\r]*)+$", "i");
				ec = ec.replace(re,"");
			}

			ec = this._postFilterContent(ec);

			if (this.relativeImageUrls) {
				// why use a regexp instead of dom? because IE is stupid
				// and won't let us set img.src to a relative URL
				// this comes after contentPostFilters because once content
				// gets innerHTML'd img urls will be fully qualified
				var siteBase = dojo.global().location.protocol + "//" + dojo.global().location.host;
				var pathBase = dojo.global().location.pathname;
				if (pathBase.match(/\/$/)) {
					// ends with slash, match full path
				} else {
					// match parent path to find siblings
					var pathParts = pathBase.split("/");
					if (pathParts.length) {
						pathParts.pop();
					}
					pathBase = pathParts.join("/") + "/";

				}

				var sameSite = new RegExp("(<img[^>]*\ src=[\"'])("+siteBase+"("+pathBase+")?)", "ig");
				ec = ec.replace(sameSite, "$1");
			}
			return ec;
		},

		close: function(/*Boolean*/save, /*Boolean*/force){
			// summary:
			//		Kills the editor and optionally writes back the modified contents to the
			//		element from which it originated.
			// save:
			//		Whether or not to save the changes. If false, the changes are discarded.
			// force:
			if(this.isClosed){return false; }

			if (arguments.length == 0) { save = true; }
			this._content = this._postFilterContent(this.editNode.innerHTML);
			var changed = (this.savedContent != this._content);

			// line height is squashed for iframes
			// FIXME: why was this here? if (this.iframe){ this.domNode.style.lineHeight = null; }

			if(this.interval){ clearInterval(this.interval); }

			if(dojo.render.html.ie && !this.object){
				dojo.event.browser.clean(this.editNode);
			}

			if (this.iframe) {
				// FIXME: should keep iframe around for later re-use
				delete this.iframe;
			}

			if(this.textarea){
				with(this.textarea.style){
					position = "";
					left = top = "";
					if(dojo.render.html.ie){
						overflow = this.__overflow;
						this.__overflow = null;
					}
				}
				if(save){
					this.textarea.value = this._content;
				}else{
					this.textarea.value = this.savedContent;
				}
				dojo.html.removeNode(this.domNode);
				this.domNode = this.textarea;
			}else{
				if(save){
					if(dojo.render.html.moz){
						var nc = dojo.doc().createElement("span");
						this.domNode.appendChild(nc);
						nc.innerHTML = this.editNode.innerHTML;
					}else{
						this.domNode.innerHTML = this._content;
					}
				}else{
					this.domNode.innerHTML = this.savedContent;
				}
			}

			dojo.html.removeClass(this.domNode, "RichTextEditable");
			this.isClosed = true;
			this.isLoaded = false;
			// FIXME: is this always the right thing to do?
			delete this.editNode;

			if(this.window._frameElement){
				this.window._frameElement = null;
			}

			this.window = null;
			this.document = null;
			this.object = null;
			this.editingArea = null;
			this.editorObject = null;

			return changed; // Boolean: whether the content has been modified
		},

		destroyRendering: function(){}, // stub!

		destroy: function (){
			this.destroyRendering();
			if(!this.isClosed){ this.close(false); }

			dojo.widget.RichText.superclass.destroy.call(this);
		},

		connect: function (targetObj, targetFunc, thisFunc) {
			// summary: convenient method for dojo.event.connect
			dojo.event.connect(targetObj, targetFunc, this, thisFunc);
		},

		disconnect: function (targetObj, targetFunc, thisFunc) {
			// summary: convenient method for dojo.event.disconnect
			dojo.event.disconnect(targetObj, targetFunc, this, thisFunc);
		},

		disconnectAllWithRoot: function (targetObj) {
			dojo.deprecated("disconnectAllWithRoot", "is deprecated. No need to disconnect manually", "0.5");
		},

		_fixContentForMoz: function(html){
			// summary:
			//		Moz can not handle strong/em tags correctly, correct them here
			html = html.replace(/<strong([ \>])/gi, '<b$1' );
			html = html.replace(/<\/strong>/gi, '<\/b>' );
			html = html.replace(/<em([ \>])/gi, '<i$1' );
			html = html.replace(/<\/em>/gi, '<\/i>' );
			return html;
		}
	}
);
