<?xml-stylesheet type="text/xsl" href="/lib/xsl/devedge-1.00/article_en.xsl"?>
<nde:article 
  xmlns:nde="http://devedge.netscape.com/2002/de"
  url="/viewsource/2003/midas/01/"
  xmlns="http://www.w3.org/1999/xhtml"  
  xmlns:ent="http://devedge.netscape.com/2003/ent"
  xml:lang="en">

  <nde:header>
    <nde:title>Rich-Text Editing in Mozilla 1.3</nde:title>
    <nde:category>Article</nde:category>
    <nde:authlist>
      <nde:author>
        <nde:authname>Doron Rosenberg</nde:authname>
        <nde:authaffil>Netscape Communications</nde:authaffil>
        <nde:email href="/community/feedback/">Feedback</nde:email>
      </nde:author>
    </nde:authlist>
    <nde:pubdate year="2003" month="04" day="04"/>
    <nde:moddate year="2003" month="07" day="01"/>
    
    <nde:channels>
      <nde:channel id="viewsource" />
      <nde:channel id="gecko" />
      <nde:channel id="ns-7" />
      <nde:channel id="ns-7.1" />
    </nde:channels>
  
    <nde:summary>
      Learn about the designMode implementation in Mozilla 1.3 which converts HTML documents into rich-text editing widgets.
    </nde:summary>  
  
  </nde:header>

  <nde:head>
    <style type="text/css">
      .sourceCode {padding-left: 5px; padding-top:5px;}        
     
      .sourceView {margin: 5px; padding: 5px; border: 1px dashed grey; font-family: Verdana,sans-serif;}
      .sourceInfo {padding-bottom: 5px; font-size: 0.9em; padding-right: 5px; border-bottom: 1px dashed gray; 
                    border-right: 1px dashed gray;}
      .tb2 {position:absolute; left:20%;}
      .tb3 {position:absolute; left:66%;}     
    </style>
  </nde:head>

  <nde:content>

  <h2>Introduction</h2>
  
  <p>
    Mozilla 1.3 introduces an implementation of Microsoft <ent:reg /> Internet Explorer's designMode feature. The rich-text editing 
    support in Mozilla 1.3 supports the designMode feature which turns HTML documents into rich-text editors.
  </p>

  <h2>Setting Up Rich-Text Editing</h2>
     
  <p>
    Rich-text editing is initialized by setting the <code>designMode</code> property of a document to "On", such as the document inside an
    iframe. Once <code>designMode</code> has been set to "On", the document becomes a rich-text 
    editing area and the user can type into it as if it were a textarea.  The most basic keyboard commands such as copy and paste 
    are available, all others need to be implemented by the website.    
  </p>
     
  
  <h2>Executing Commands</h2>  
  <p>
    When an HTML document has been switched to <code>designMode</code>, the document object exposes the <code>execCommand</code> method
    which allows one to run commands to manipulate the contents of the editable region.  Most commands affect the document's selection 
    (bold, italics, etc), while others insert new elements (adding a link) or affect an entire line (indenting).
  </p>
  
  <p>
    <dt>execCommand(String aCommandName, Boolean aShowDefaultUI, String aOptionalCommandArgument)</dt>
    <dd>
      <strong>Arguments:</strong><br />
      String aCommandName - the name of the command<br /><br />
      Boolean aShowDefaultUI - whether the default user interface should be shown.  This is not implemented in Mozilla.<br /><br />
      String aOptionalCommandArgument - some commands (such as insertimage) require an extra argument (the image's url<br /><br />
    </dd>
    
    <dt><strong>Commands</strong></dt>
    <dd>
      <dl>
        <dt>bold</dt>
        <dd>
          <p>toggles the bold attribute of the selected text.</p>
        </dd>
      </dl> 
      <dl>
        <dt>createlink</dt>
        <dd>
          <p>generates a link from the selected text.  <em>Requires the URI to be passed in as the optional argument.</em></p>
        </dd>
      </dl> 
      <dl>
        <dt>delete</dt>
        <dd>
          <p>deletes the current selection.</p>
        </dd>
      </dl>         
      <dl>
        <dt>fontname</dt>
        <dd>
          <p>changes the fontname of the selected text. <em>Requires the name of font ("Arial" for example) to be passed in as the 
          optional argument.</em></p>
        </dd>
      </dl> 
      <dl>
        <dt>fontsize</dt>
        <dd>
          <p>changes the fontsize of the selected text. <em>Requires the size to be passed in as the 
          optional argument.</em></p>
        </dd>
      </dl>
      <dl>
        <dt>fontcolor</dt>
        <dd>
          <p>changes the fontcolor of the selected text. <em>Requires the color to be passed in as the 
          optional argument.</em></p>
        </dd>
      </dl>
      <dl>
        <dt>indent</dt>
        <dd>
          <p>indents the text block where the caret is located.</p>
        </dd>
      </dl>
      <dl>
        <dt>inserthorizontalrule</dt>
        <dd>
          <p>inserts an horizontal rule at the cursor's location.</p>
        </dd>
      </dl>
      <dl>
        <dt>insertimage</dt>
        <dd>
          <p>inserts an image at the cursor's location. <em>Requires the url of the image to be passed in as the 
          optional argument.</em></p>
        </dd>
      </dl>
      <dl>
        <dt>insertorderedlist</dt>
        <dd>
          <p>inserts an ordered list.</p>
        </dd>
      </dl>      
      <dl>
        <dt>insertunorderedlist</dt>
        <dd>
          <p>inserts an unordered list.</p>
        </dd>
      </dl>
      <dl>
        <dt>italic</dt>
        <dd>
          <p>toggles italicize attribute of the selected text.</p>
        </dd>
      </dl>
      <dl>
        <dt>justifycenter</dt>
        <dd>
          <p>centers the current line.</p>
        </dd>
      </dl>
      <dl>
        <dt>justifyleft</dt>
        <dd>
          <p>justifies the current line to the left.</p>
        </dd>
      </dl>
      <dl>
        <dt>justifyright</dt>
        <dd>
          <p>justifies the current line to the right.</p>
        </dd>
      </dl>
      <dl>
        <dt>outdent</dt>
        <dd>
          <p>outdents the current line if it was indented before.</p>
        </dd>
      </dl>
      <dl>
        <dt>redo</dt>
        <dd>
          <p>redoes the previously undo command.</p>
        </dd>
      </dl>
      <dl>
        <dt>removeformat</dt>
        <dd>
          <p>removes all formatting from the current selection.</p>
        </dd>
      </dl>
      <dl>
        <dt>selectall</dt>
        <dd>
          <p>selects all of the content of the editable region.</p>
        </dd>
      </dl>
      <dl>
        <dt>strikethrough</dt>
        <dd>
          <p>toggles strikethrough attribute of the selected text.</p>
        </dd>
      </dl>
      <dl>
        <dt>subscript</dt>
        <dd>
          <p>converts the current selection to subscript.</p>
        </dd>
      </dl>
      <dl>
        <dt>superscript</dt>
        <dd>
          <p>converts the current selection to superscript.</p>
        </dd>
      </dl>
      <dl>
        <dt>underline</dt>
        <dd>
          <p>toggles underlining of the selected text.</p>
        </dd>
      </dl>
      <dl>
        <dt>undo</dt>
        <dd>
          <p>undoes the last executed command.</p>
        </dd>
      </dl>
      <dl>
        <dt>unlink</dt>
        <dd>
          <p>removes the link information from the current selection.</p>
        </dd>
      </dl>  
      <dl>
        <dt>useCSS</dt>
        <dd>
          <p>toggles the use of css for the generated markup. <em>Requires a boolean indicating if to turn CSS generation on
          or off as the optional argument.</em></p>
        </dd>
      </dl>       
         
    </dd>    
  </p>    
    
  <h2>Internet Explorer Differences</h2>
 
  <p>
    Mozilla does not support Internet Explorer's contentEditable attribute which allows any element to become editable.
    One major difference between Mozilla and Internet Explorer that affects designMode is the generated code in the editable document: 
    while Internet Explorer uses HTML tags (em, i, etc), Mozilla 1.3 will generate by default spans with inline style rules.  The
    <code>useCSS</code> command can be used to toggle between CSSand HTML markup creation.
  </p>
  
  <p>     
    <div class="sourceView">
      <span class="sourceInfo">Figure 1 : Generated HTML differences</span>
    
      <p class="sourceCode">
        <strong>Mozilla:</strong><br />
        &lt;span style="font-weight: bold;">I love geckos.&lt;/span><br />
        &lt;span style="font-weight: bold; font-style: italic; text-decoration: underline;">Dinosaurs are big.&lt;/span><br /><br />
        
        <strong>Internet Explorer:</strong><br />
        &lt;STRONG>I love geckos.&lt;/STRONG><br />
        &lt;STRONG>&lt;EM>&lt;U>Dinosaurs are big.&lt;/U>&lt;/EM>&lt;/STRONG>
      </p>
    </div>
  </p>
  
  <p>
    Another difference between Mozilla and IE is how to access the document object of an iframe, which is usually used in conjunction
    with <code>designMode</code>.  Mozilla uses the W3C standard way, 
    namely <code>IFrameElement.<a href="http://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-38538621">contentDocument</a></code>, 
    while IE requires <code>IFrameElement.document</code>.
  </p>  
  
  <p>
    DevEdge provides a JavaScript helper class, <a href="/toolbox/examples/2003/xbDesignMode/">xbDesignMode</a>, which
    is a wrapper for the designMode feature which hides the differences between IE and Mozilla.
  </p>

  
  <h2>Examples</h2>  

  <h3>Example 1</h3>
  <p>
    The first example is an HTML document setting its own <code>designMode</code> to "On".  This makes the entire document
    editable in Mozilla 1.3.  Internet Explorer, however, does not allow javascript to change the current document's designMode. For it
    to work in Internet Explorer, the <code>contentEditable</code> attribute of the <code>body</code> tag needs to be set to "true".
    The example can be found <a href="example1.html" target="_blank">here</a>.
  </p>
  
   <p>     
    <div class="sourceView">
      <span class="sourceInfo">Figure 2 : First example - <a href="example1.html" target="_blank">View Example</a></span>
    
      <p class="sourceCode">      
        <strong>HTML:</strong><br />
        &lt;body contentEditable="true" onload="load()"><br /><br />
        
        <strong>JavaScript:</strong><br />

        function load(){<br />
          &#160;&#160;window.document.designMode = "On";<br />
        }
      </p>     
    </div>        
  </p>  
  

  <h3>Example 2</h3>

  <p>
    The second example is a simple rich text editing page, where text can be bolded/italicized/underlined, new links can be added and
    the color of text changed.  The example page consists of an iframe, which will be the rich editing area, as well as elements for 
    basic editing commands such as bold/italics/text color.  Also provided is a "view source" button that will display the generated code 
    in the iframe's document.  The example can be found <a href="example2-index.html" target="_blank">here</a>.
  </p>
  
  <div><iframe src="example2-index.html" width="100%" height="260"></iframe></div>

  <p>   
    Once the HTML page has finished loading, the example switches the iframe's document to designMode.
  </p>
  
 <p>     
    <div class="sourceView">
      <span class="sourceInfo">Figure 3 : Setting up rich-text editing</span>
    
      <p class="sourceCode">      
        <strong>HTML:</strong><br />
        &lt;body onload="load()"><br /><br />
        
        <strong>JavaScript:</strong><br />
        function load(){<br />
          &#160;&#160;getIFrameDocument("editorWindow").designMode = "On";<br />
        }<br /><br />
    
        function getIFrameDocument(aID){<br />
          &#160;&#160;// if contentDocument exists, W3C compliant (Mozilla)<br />
          &#160;&#160;if (document.getElementById(aID).contentDocument){<br />
            &#160;&#160;&#160;&#160;return document.getElementById(aID).contentDocument;<br />
          &#160;&#160;} else {<br />
            &#160;&#160;&#160;&#160;// IE<br />
            &#160;&#160;&#160;&#160;return document.frames[aID].document;<br />
          &#160;&#160;}<br />
        }
      </p>     
    </div>        
  </p>  
 
  <p>
    The example contains a <code>doRichEditCommand</code> function that makes it easier to execute commands on the iframe's document
    and keeps the HTML code clean.  The function executed the requested command using <code>execCommand()</code> and then
    sets focus back to the editable document, as clicking on a button will set focus on the button itself, which breaks the editing
    flow.
  </p>
  
  <p>     
    <div class="sourceView">
      <span class="sourceInfo">Figure 4 : Executing Rich Editing Commands</span>
    
      <p class="sourceCode">      
        <strong>HTML:</strong><br />
        &lt;button onclick="doRichEditCommand('bold')" style="font-weight:bold;">B&lt;/button><br /><br />
        
        <strong>JavaScript:</strong><br />
        function doRichEditCommand(aName, aArg){<br />
          &#160;&#160;getIFrameDocument('editorWindow').execCommand(aName,false, aArg);<br />
          &#160;&#160;document.getElementById('editorWindow').contentWindow.focus()<br />
        }
      </p>     
    </div>        
  </p>  
     
  <h2>Resources</h2>

  <p>
    <ul>
      <li><a href="http://mozilla.org/editor/midas-spec.html">mozilla.org's rich-text editing Specification</a></li>
      <li><a href="http://mozilla.org/editor/midasdemo/">mozilla.org's rich-text editing Demo</a></li>    
      <li><a href="http://www.mozilla.org/editor/ie2midas.html">Converting an app using document.designMode from IE to Mozilla</a> at mozilla.org</li>   
      <li><a href="http://msdn.microsoft.com/workshop/author/dhtml/reference/properties/designmode.asp">MSDN Documentation on designMode</a></li>    
      <li><a href="http://msdn.microsoft.com/downloads/samples/internet/default.asp?url=/downloads/samples/internet/ie55/EditRegions/default.asp">MSDN Demo</a></li>
      <li><a href="http://www.kevinroth.com/rte/demo.htm">A open source, cross-browser rich-text editing demo</a></li>
    </ul>    
  </p>
          
  <h2>Bugs</h2>

  <p>
    <a href="http://bugzilla.mozilla.org/show_bug.cgi?id=209836">Bug 209836 - designMode still active after clicking Back</a>.
  </p>
  <dl>
    <dt>
      Problem
    </dt>
    <dd>
      <p>
        Once <code>document.designMode</code> has been set for the <code>document</code>
        object in a window, all documents in that window for that domain will remain
        editable.
      </p>
    </dd>
    <dt>
      Solution
    </dt>
    <dd>
      <p>
        Edit the document in a separate window or contained in an <code>IFRAME</code>.
      </p>
    </dd>
  </dl>

</nde:content>

  <nde:related area="nde">
    <nde:item url="/central/gecko">Gecko Central</nde:item>
    <nde:item url="/library/releases/netscape-7.1/">Other Articles about Netscape 7.1</nde:item>
  </nde:related> 

  <nde:related area="ext">
    <nde:item url="http://mozilla.org/editor/midas-spec.html">Rich-text editing Spec</nde:item>
    <nde:item url="http://mozilla.org/editor/midasdemo/">Rich-text editing Demo</nde:item>
    <nde:item url="http://msdn.microsoft.com/workshop/author/dhtml/reference/properties/designmode.asp">MSDN Documentation</nde:item>
    <nde:item url="http://msdn.microsoft.com/downloads/samples/internet/default.asp?url=/downloads/samples/internet/ie55/EditRegions/default.asp">MSDN Demo</nde:item>
  </nde:related>
  
</nde:article>
