5

The example below is a simple example of an iframe which uses window.parent.[turn designmode on] (this works). In FF all is well, but in IE8 (surprise surprise) any selection made is lost when you click out of the iframe. This totally negates the use of tools outside the iframe. I cannot find a solution 4 days later...

Open in IE8 http://www.chromedigital.co.za/hydrapage/test.htm

Johnny Darvall
  • 587
  • 2
  • 7
  • 17
  • You're doing it wrong. Try this `contenteditable` demo in your IE8: http://www.quirksmode.org/dom/execCommand/ It uses an iframe for the editable region as well, and from all accounts it works fine. – Crescent Fresh Sep 24 '09 at 12:12
  • I don't understand. While I'm not convinced by the code for setting designMode in the original question, the demo you've linked exhibits exactly the same behaviour with selections that this question is asking about. – Tim Down Sep 24 '09 at 13:47
  • @Tim: I don't have IE8 but I do have IE7, and the demo definitely does *not* lose the selection when interacting with the top buttons. Johnny may have found a legitimate bug in IE8. @Johnny, did you try the demo yet? – Crescent Fresh Sep 25 '09 at 02:21
  • OK, I get it. I didn't try the buttons but did click on the main document and then back into the iframe, and IE does the lose the selection then. @Johnny, what kind of tools are breaking the selection? – Tim Down Sep 25 '09 at 08:35
  • Hi crescentfresh - did try the demo and found that selection is lost if click ouside iframe - exept if click on buttons - then its ok - does this mean that all ie8 richtext can only be edited through buttons? – Johnny Darvall Sep 26 '09 at 10:34
  • IE has never had "partial" selections like you both are describing. It does visually maintain the focus if you interact with form elements, however mousing down anywhere else (inside the iframe or not) loses the selection. This has always been the case. – Crescent Fresh Sep 28 '09 at 13:52
  • @crescentfresh Yes, that's true. I've lost track of where we're at in terms of what the OP is trying to achieve. I do still think a script to save and restore the selection in the iframe when it loses and gains focus could be useful, which is what my answer provides. – Tim Down Oct 01 '09 at 11:12

3 Answers3

12

On any element in the main document you want not to break the iframe selection, add unselectable="on".

For example:

<div onclick="makeBold()" unselectable="on">Bold</div>
Tim Down
  • 318,141
  • 75
  • 454
  • 536
3

You could try saving the selection when the iframe loses focus. If you're sure the content of the iframe will not change before the user focuses on it again, you can store the currently selected Range or TextRange. The following script (for the main page) includes your original script, is not extensively tested and would be improved with better feature detection but is something to work with:

h_FF=!document.all
h_rt_F=0

function HLC_DM()
{
 h_rt_F=document.getElementById("moo").contentWindow
 if(h_FF)
 {
  if(h_rt_F.document.designMode!="on")
  {
   try
   {
    h_rt_F.document.designMode="on"
    h_rt_F.document.execCommand("redo",false,null)
    createEventHandlers();
   }
   catch(e)
   {
    setTimeout("HLC_DM",200)
    return false
   }
  }
 }
 else
  h_rt_F.document.body.contentEditable=true
  createEventHandlers();
}


function getContentWindow() {
 return document.getElementById("moo").contentWindow;
}

function saveSelection() {
 var win = getContentWindow();
 var doc = win.document;
 var sel = win.getSelection ? win.getSelection() : doc.selection;
 var range;

 if (sel) {
  if (sel.createRange) {
   range = sel.createRange();
  } else if (sel.getRangeAt) {
   range = sel.getRangeAt(0);
  } else if (sel.anchorNode && sel.focusNode && doc.createRange) {
   // Older WebKit browsers
   range = doc.createRange();
   range.setStart(sel.anchorNode, sel.anchorOffset);
   range.setEnd(sel.focusNode, sel.focusOffset);

   // Handle the case when the selection was selected backwards (from the end to the start in the
   // document)
   if (range.collapsed !== sel.isCollapsed) {
    range.setStart(sel.focusNode, sel.focusOffset);
    range.setEnd(sel.anchorNode, sel.anchorOffset);
   }
  }
 }
 return range;
}

function restoreSelection(range) {
 var win = getContentWindow();
 var doc = win.document;
 var sel = win.getSelection ? win.getSelection() : doc.selection;

 if (sel && range) {
  if (range.select) {
   range.select();
  } else if (sel.removeAllRanges && sel.addRange) {
   sel.removeAllRanges();
   sel.addRange(range);
  }
 }
}

var selectedRange;

function blurHandler() {
 selectedRange = saveSelection();
}

function focusHandler() {
 if (selectedRange) {
  restoreSelection(selectedRange);
 }
}

var iframeHandlersCreated = false;
function createEventHandlers() {
 // Prevent setting up twice
 if (!iframeHandlersCreated) {
  var iframe = document.getElementById("moo");
  var doc;
  if (iframe.contentDocument && iframe.contentDocument.addEventListener) {
   doc = iframe.contentDocument;
   doc.addEventListener("blur", blurHandler, false);
   doc.addEventListener("focus", focusHandler, false);
  } else if (iframe.attachEvent) {
   iframe.attachEvent("onbeforedeactivate", blurHandler);
   iframe.attachEvent("onfocus", focusHandler);
  }
  iframeHandlersCreated = true;
 }
}
Tim Down
  • 318,141
  • 75
  • 454
  • 536
  • 1
    How the hell has this been downvoted?? Not only does it fully answer the question, it's quite an involved answer that took some effort to write. – Tim Down Sep 24 '09 at 23:19
  • Hi Tim - thanks for your effort here - the demo i provided was to indicate the loss of selection only - the real code does store and process the range - however, i want to determine if this is a bug or a native behavior in ie8. If its not a bug - then ill use your code (but its shame to have all this extra overhead to maintain a selection) - i might just restrict editing to gecko. ie blows – Johnny Darvall Sep 26 '09 at 10:40
  • Im disecting the demo crescentfresh provided. Mabe there is a solution in there - those buttons do not kill the selection - Ill update on my find... – Johnny Darvall Sep 26 '09 at 10:46
  • ok - after reviewing the demo code it seems - that it must be a bug. In my updated example http://www.chromedigital.co.za/hydrapage/test.htm make selection then click on the button, then on elsewhere. It seems ie8 design-mode will lose its selection provided you click on inputs. This will definitely wreck a lot of current rich text editors... – Johnny Darvall Sep 26 '09 at 11:10
0

My Editbox can add images, tables etc where you last clicked in the iframe and works for ie6, ie7 and FF but for ie8 it adds then at the start. They can then be cut and pasted to where you want them but that is a nuisance. MORE SERIOUS is that when I want to change the attributes of a table cell, for example, I have to have some text now in the cell which I must highlight or I can't determine what element I'm in!

Have Microsoft any bug fixes for the selection method or is Firefox or old versions of ie the only course?

regards Mike W