views:

305

answers:

2

My current project involves working with a document editor that, for better or worse, is implemented using mshtml and setting contentEditable to true. We're certainly considering replacing this setup with something else, but for the moment assume it is not an option.

In case it matters, we're doing this using VS 2008 (.Net 3.5) & C#:

document = (HtmlDocument)this.editorWebBrowser.Document;
body = (HtmlBody)document.body;
body.contentEditable = true;

We'd like to hide most of the structural editing behind our UI, but let the user edit the text any way they like. The problem arises when we add a div with any of several styles:

(Adding a body tag to simulate what we're doing programmatically, so you can test in IE, but remember we're working in C#/.Net/VS.)

<BODY contentEditable="true">
  <DIV class="intro" style="border: 1px solid blue; width=100%;">
    <P>My Intro</P>
  </DIV>
  <P>Other Text</P>
</BODY>

There are two things wrong with this:

  1. The first click by the user selects the div. We'd like the click to go straight to the text, and never let the user see the resize handles.
  2. If the user places the cursor in Other Text then tries to move to the div text using the keyboard, they're prevented. The div is treated as one character when you are outside of it moving around.

So, effectively, is there any way to make the div behave like just a background decoration, but have everything around it still be editable? This html is completely internal, so we can do anything with it we like. So the div itself doesn't matter. What matters is that we:

  • Contain several P or other tags
  • Show the user visually that all the contained P or other tags are part of one group, as styling like border & background color on the current div accomplish now.

This SO question makes me worried that what I want isn't possible with our current setup, but I ask to help anyone else who stumbles on a similar problem. I'll be adding a couple imperfect solutions we've come up with in a moment.

Possible or not, thanks for any thoughts you might have.

A: 

Partial solution: Set a containing div to contentEditable=false, then true again on an inner element, like so:

<BODY contentEditable="true">
  <DIV class="intro" contentEditable="false" style="border: 1px solid blue; width=100%;">
    <P contentEditable="true">My Intro</P>
  </DIV>
  <P>Other Text</P>
</BODY>

This possibly solves problem 1 (user selecting the div) but does nothing about problem 2.

Willfulwizard
A: 

Since the HTML is internal and doesn't need to play nice with anything else, just represent the area with a table, rather than a div:

<table class="intro">
  <tbody>
    <tr>
      <td>
        Intro
      </td>
    </tr>
  </tbody>
</table>

This solves both problems, but significantly complicates the code for editing or parsing. We'd prefer a cleaner solution.

Willfulwizard