Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 2 of 2
  1. #1
    New Coder
    Join Date
    Sep 2002
    Location
    Moncton, N.B., Canada
    Posts
    69
    Thanks
    0
    Thanked 0 Times in 0 Posts

    undo and redo Problems: execCommand

    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,
    -Terry

  • #2
    Regular Coder
    Join Date
    Jul 2002
    Posts
    165
    Thanks
    0
    Thanked 0 Times in 0 Posts
    I'm sorry but right now haven't got much time, I've completed 3 such editors using every feature each type is supposed to allow you to use, so later on (when I go home) you can get in touch with me at protorium_exodious@hotmail.com (on msn or email) and I can give share some of my own with you.

    Right now though, if anyone reads this, the problem is here

    Code:
    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>';
    		
    	 }
    	}
    }
    You are opening the document and then writing the content, closing the document which is resetting the execCommand's state back to just arriving on the page for the first time

    You can overcome this by using something like (check my first ever test of one...)

    document.theIframe.DocumentHTML = "HTML content";

    That should sort it, if ur still stuck and noone else can help, get in touch later (or do so anyway, and I'll show you some other uses of the execCommand, its restrictions etc... and other options)

    Protorium - Hope it helps


  •  

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •