Hi,

I'm making a js/html editor so I can open, edit and save files on my computer. The editor is a textarea and to view the page I use an embedded iframe to stream the textarea contents to it.

The problem I'm having is when I click the view button and write the contents to the iframe - the undo and redo stop working. All the other toolbar functions work after a write to the iframe (paste, copy, cut, and save) except the undo and redo.

I'm not sure why this is happenning, but I have a suspicion its a focus or bubble issue.

Even if I do an innerHTML event (in the main document or the iframe document), the undo and redo stop working.

My page is an HTA Application. I can paste the code and maybe someone can tell me what is going on, I'll also supply a zipped version.

I put 2 buttons at the bottom that only change the z-index of the iframe and textarea for display. This is as a test to show that the undo and redo will continue to work if you press the bottom buttons. The reason is that they don't initiate any stream to iframe, but only change the z-index display properties of the elements.

I hope my explanation has been clear enough to understand. Any help would be appreciated.

Code:
<html xmlns:msie>
<msie:download id="downloader"
               style="behavior:url(#default#download)" />
<head>
<HTA:APPLICATION 
   ID = "oApp"
   APPLICATIONNAME = "HTA Editor"
   BORDER = "thick"
   CAPTION = "yes"
   ICON = "js.ico"
   SHOWINTASKBAR = "yes"
   SINGLEINSTANCE = "yes"
   SYSMENU = "yes"
   WINDOWSTATE = "normal"
   SCROLL = "no"
   SCROLLFLAT = "yes"
   VERSION = "1.0"
   INNERBORDER = "yes"
   SELECTION = "no"
   MAXIMIZEBUTTON = "yes"
   MINIMIZEBUTTON = "yes"
   NAVIGABLE = "yes"
   CONTEXTMENU = "yes"
   BORDERSTYLE = "normal"
   >

<title>HTA Application: Javascript Editor</title>
<style type="text/css">
body { 
	background:buttonface;
	border:0px;padding: 0px;
	margin: 0px;	
}

textarea {
	width: 100%; height: 400px;
	background: #f9f9f9; 
	font: 13px "courier new", monospaced;
	position: absolute; 
	top: 25px; left: 0px;
	z-index: 20;
}

#iFrameDisplay 
{
	position: absolute; 
	top: 25px; left: 0px;
	width: 100%;
	border: none;
	height: 400px;
	z-index: 10;
}

ul#tabnav {
	font: bold 11px verdana, arial, sans-serif;
	list-style-type: none;
	margin: 0;
	position: absolute;
	top: 6px;
}

ul#tabnav li {
	float: left;
	height: 17px;
	background: url(images/menuBg.gif) repeat-x;
	margin: 2px 1px;
	border: 1px solid #91A7B4;
}

#tabnav a {
	float: left;
	display: block;
	color: #666;
	text-decoration: none;
	padding: 2px 4px;
}

.on {
	float: left;
	display: block;
	background: #f9f9f9;
	padding: 2px 4px;
}

#tabnav a:hover {
	background: #eee;
	color: #000;
}

#toolbar {
			margin: 0;
			padding: 0;
			background: transparent;
			text-align:left;
			position: absolute;
			top: 0px; 
			left: 230px;
			z-index: 20;
		  	}

.button 	{
			background: transparent;
			border-width: 1px;
			border-style: solid;
			border-color: buttonface;
			margin: -10px 0px;
			}

.raised	{
			border-top: 1px solid #f9f9f9;
			border-left: 1px solid #f9f9f9;
			border-bottom: 1px solid #999;
			border-right: 1px solid #999;
			background: transparent;
			margin: -10px 0px;
			}

.pressed	{
			border-top: 1px solid #999;
			border-left: 1px solid #999;
			border-bottom: 1px solid #f9f9f9;
			border-right: 1px solid #f9f9f9;
			background: transparent;
			margin: -10px 0px;
			}
.del {
	color: #999; width: 1px; height: 15px; border: 1px inset; 
	height: 17px; margin: 5px 2px;
}

#toolbarDisplay {
	font: 8pt Verdana, sans-serif; width: 200px; height: 17px;
	text-align: left; border: 1px inset; padding: 2px; 
	position: absolute; top: 4px; left: 400px;
}
</style>

<script language="JScript">
function loadFile(fileName) 
{
	if (document.all && document.getElementById)
   downloader.startDownload(fileName, displayFile);
}

function displayFile(text) 
{
 document.formName.file.value = text;
}

function CheckTab(el) {

  if ((document.all) && (9 == event.keyCode))
  {
   el.selection =document.selection.createRange();
	el.selection.text = String.fromCharCode(32) + String.fromCharCode(32);
	event.returnValue = false;
  }
}

function mouseover() {
	 var e = event.srcElement;
	  //toolbarDisplay.innerHTML = e.name;
    if ( e.nodeName != 'IMG' ) return;
	 e.className = "raised";
	 
}

function mouseout() {
	 var e = event.srcElement;
	 //toolbarDisplay.innerHTML = "";
    if ( e.nodeName != 'IMG' ) return;
  	 e.className = "button";
	 
}

function mousedown() {
	 var e = event.srcElement;
    if ( e.nodeName != 'IMG' ) return;
  	 e.className = "pressed";
	 if(e.name == 'save') SaveDocument();
	 else document.execCommand(e.name);
}

function mouseup() {
	 var e = event.srcElement;
    if ( e.nodeName != 'IMG' ) return;
  	 e.className = "raised";
	 document.formName.file.focus();
}

function pasteIt()
{
	document.formName.file.selection = document.execCommand('Paste');
}

function SaveDocument()
{
	// Setting CancelError to true and using try/catch 
	// allows the user to click cancel on the save as 
	// dialog without causing a script error
  	cDialog.CancelError = true;
  	fileTxt = document.formName.file;
  	try{
  		cDialog.Filter="HTM Files (*.htm)|*.htm|"
		+ "Text Files (*.txt)|*.txt|"
		+ "JS Files (*.js)|*.js|"
		+ "CSS Files (*.css)|*.css"
  		cDialog.ShowSave();
  		var fso = new ActiveXObject("Scripting.FileSystemObject");
  		var f = fso.CreateTextFile(cDialog.filename,  true);
  		f.write(fileTxt.value);
  		f.Close();
  		sPersistValue = fileTxt.value;
  	}
  	catch(e){
  		var sCancel = "true";
  		return sCancel;
  	}
	fileTxt.focus();	
}

var tabStrs = ["Editor","View Page","Snippets"];
function tabOn(el, str)
{
	var output = "<span class=\"on\">"
	+ str + "</span>";
	el.innerHTML = output;
	switch(str)
	{
		case 'Editor':
		showEditor();
		break;
		case 'View Page':
		showIframe();
		doc = parent.frames['ifd'].document;
		doc.write(document.formName.file.value);
		doc.close();
		break;
	}
	for(var i = 0; i < tabStrs.length; i++)
	{
	 if(tabStrs[i] != str)
	 {
	 	var element = eval(tabStrs[i].substring(0,1).toLowerCase());
		element.innerHTML = 
			'<a href="#">' + tabStrs[i] + '</a>';
		
	 }
	}
}
function showEditor()
{
	document.getElementById('editor').style.zIndex = '20'; 
	document.getElementById('iframeDisplay').style.zIndex = '10';
}

function showIframe(code)
{
	document.getElementById('editor').style.zIndex = '10'; 
	document.getElementById('iframeDisplay').style.zIndex = '20';
}
</script>
</head>
<body onLoad="document.formName.file.focus();">
<OBJECT ID="cDialog" WIDTH="0px" HEIGHT="0px"
    CLASSID="CLSID:F9043C85-F6F2-101A-A3C9-08002B2F49FB"
    CODEBASE="http://activex.microsoft.com/controls/vb5/comdlg32.cab">
</OBJECT>
<ul id="tabnav">
	<li id="e" onclick="tabOn(this,'Editor');"><span class="on">Editor</span></li>
	<li id="v" onclick="tabOn(this,'View Page');"><a href="#">View Page</a></li>
	<li id="s" onclick="tabOn(this,'Snippets');"><a href="#">Snippets</a></li>
</ul>
	<div id="toolbar" onmouseover="mouseover();"
	 onmouseout="mouseout();"
	 onmousedown="mousedown();"
	 onmouseup="mouseup();" 
	 style="font:7pt verdana, sans-serif;">
	<img class="button"
	 onclick="SaveDocument();"
	 src="images/save.gif"
	 width="21" height="20"
	 align="middle"
	 name="save" alt="save" />
	<span class="del"></span>
	<img class="button"
	 src="images/cut.gif"
	 width="21" height="20"
	 align="middle"
	 name="cut" />
	<img class="button"
	 src="images/copy.gif"
	 width="21" height="20"
	 align="middle"
	 name="copy" />
	<img class="button"
	 src="images/paste.gif"
	 width="20" height="21"
	 align="middle"
	 name="paste" />
	<span class="del"></span>
	<img class="button"
	 src="images/undo.gif"
	 width="20" height="21"
	 align="middle"
	 name="undo" />
	<img class="button"
	 src="images/redo.gif"
	 width="20" height="21"
	 align="middle"
	 name="redo" />
	 </div>
<div id="toolbarDisplay"></div>
<form id="formName" name="formName">
	<textarea wrap="soft"
	id="editor" onkeydown="CheckTab(this)"
	name="file"><html>
<head>
<title>Test Page</title>
<style type="text/css">

</style>
<script type="text/javascript">

</script>
</head>

<body>

HTML Markup

</body>
</html></textarea>

<div style="position: absolute; top: 426px; left: 90%;">
<input type="button" onclick="document.getElementById('editor').style.zIndex = '20'; 
	document.getElementById('iframeDisplay').style.zIndex = '10';" value="textarea" />&nbsp;
<input type="button" onclick="document.getElementById('editor').style.zIndex = '10'; 
	document.getElementById('iframeDisplay').style.zIndex = '20';" value="iframe" />
</div>
</form>
<iframe id="iframeDisplay" name="ifd"></iframe>
</body>
</html>
ZIP FILE: http://www.xdevdesign.com/hta.zip

Thanks,
-xDev