<?xml version="1.0"?>

<!-- TODO Summary
 
Inteface:
  - Context bar - readonly for parenttag..

Table:
 support:  (THEAD, CAPTION, TFOOT, TH, ...

Extra tags:
  - DL/DD/DT (Data Definitions?)
  - HR
  - APPLET??? << evil java ;)
  - OBJECT / PARAM??? << inserting flash movies -> add on to image pulldown?
  - SPAN/DIV?:


-->



<bindings id="xulHtmlEdit"
   xmlns="http://www.mozilla.org/xbl"
   xmlns:html="http://www.w3.org/TR/REC-html40"
   xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
  
    <binding id="htmledit" extends="xul:box" inherits="value">
        <!-- ::::::::::::::::: CONTENT ::::::::::::::::::::::::: -->
        <content id="content">
         

            <xul:vbox flex="0">
            
            
                <xul:popup id="specialChars" position="after_end">
                 <xul:grid>
                   <xul:rows>
                     <xul:row>
                       <xul:menuitem label="&#169;"      oncommand="this.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.insertSymbol(this);"/>
                       <xul:menuitem label="&#174;"     oncommand="this.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.insertSymbol(this);"/>
                       <xul:menuitem label="&#8482;"    oncommand="this.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.insertSymbol(this);"/>
                       <xul:menuitem label="&#163;"     oncommand="this.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.insertSymbol(this);"/>
                     </xul:row>
                     <xul:row>
                       <xul:menuitem label="&#8212;"    oncommand="this.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.insertSymbol(this);"/>
                       <xul:menuitem label="&#8230;"    oncommand="this.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.insertSymbol(this);"/>
                       <xul:menuitem label="&#247;"     oncommand="this.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.insertSymbol(this);"/>
                       <xul:menuitem label="&#225;"     oncommand="this.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.insertSymbol(this);"/>
                     </xul:row>
                     <xul:row>
                       <xul:menuitem label="&#165;"     oncommand="this.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.insertSymbol(this);"/>
                       <xul:menuitem label="&#8364;"    oncommand="this.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.insertSymbol(this);"/>
                       <xul:menuitem label="&#8220;"    oncommand="this.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.insertSymbol(this);"/>
                       <xul:menuitem label="&#8221;"    oncommand="this.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.insertSymbol(this);"/>
                     </xul:row>
                     <xul:row>
                       <xul:menuitem label="&#8226;"    oncommand="this.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.insertSymbol(this);"/>
                       <xul:menuitem label="&#176;"     oncommand="this.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.insertSymbol(this);"/>
       <!--          <xul:menuitem label="&#182;"        oncommand="this.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.insertSymbol(this);"/> -->
                       <xul:menuitem label="&#233;"     oncommand="this.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.insertSymbol(this);"/>
                       <xul:menuitem label="&#250;"     oncommand="this.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.insertSymbol(this);"/>
                     </xul:row>
                   </xul:rows>
                 </xul:grid>
               </xul:popup>

             
            
             <xul:popup id="formElementPopup" position="after_end">
                 <xul:vbox>
                       <!--  
                       We really should flag these somehow,  - so that you can turn them on off with config opts..
                       <xul:menuitem label="form"               oncommand="this.parentNode.parentNode.parentNode.parentNode.insertFormElement(this);"/>
                       -->
                       <xul:menuseparator/>
                       <xul:menuitem label="input: text"        oncommand="this.parentNode.parentNode.parentNode.parentNode.insertFormElement(this);"/>
                       <!-- what's the point in this one...
                       <xul:menuitem label="input: hidden"      oncommand="this.parentNode.parentNode.parentNode.parentNode.insertFormElement(this);"/> 
                       -->
                       <xul:menuitem label="input: checkbox"    oncommand="this.parentNode.parentNode.parentNode.parentNode.insertFormElement(this);"/>
                       <xul:menuitem label="input: radio"       oncommand="this.parentNode.parentNode.parentNode.parentNode.insertFormElement(this);"/>
                       <xul:menuitem label="input: password"    oncommand="this.parentNode.parentNode.parentNode.parentNode.insertFormElement(this);"/>
                       <!-- 
                       <xul:menuitem label="input: submit"      oncommand="this.parentNode.parentNode.parentNode.parentNode.insertFormElement(this);"/>
                       <xul:menuitem label="input: button"      oncommand="this.parentNode.parentNode.parentNode.parentNode.insertFormElement(this);"/> 
                       -->
                       <xul:menuseparator/>
                       <xul:menuitem label="select"     oncommand="this.parentNode.parentNode.parentNode.parentNode.insertFormElement(this);"/>
                       <xul:menuseparator/>
                       <xul:menuitem label="textarea"     oncommand="this.parentNode.parentNode.parentNode.parentNode.insertFormElement(this);"/>
                       <xul:menuseparator/>
                       <xul:menuitem label="label"     oncommand="this.parentNode.parentNode.parentNode.parentNode.insertFormElement(this);"/>
                    </xul:vbox>
            </xul:popup>

            
            
            
                <xul:toolbar anonid="editToolbar">
                   
                    <xul:menulist id="formatblock" value="xxx" maxwidth="150">
                        <xul:menupopup  anonid="formatmenupopup"
                          onpopuphiding="this.parentNode.parentNode.parentNode.parentNode.setStyle(this.parentNode);">
                            <xul:menuitem value="" label="--Format--"/>
                            <xul:menuitem value="p" label="Normal Paragraph"/>
                            <xul:menuseparator/>
                            <xul:menuitem value="h1" label="Heading 1"/>
                            <xul:menuitem value="h2" label="Heading 2"/>
                            <xul:menuitem value="h3" label="Heading 3"/>
                            <xul:menuitem value="h4" label="Heading 4"/>
                            <xul:menuitem value="h5" label="Heading 5 "/>
                            <xul:menuitem value="h6" label="Heading 6"/>
                            <xul:menuseparator/>
                            <xul:menuitem value="pre" label="PRE Formatted"/>
                            <xul:menuitem value="code" label="Source CODE"/>
                            <xul:menuseparator/>
                            <xul:menuitem value="abbr" label="Abbreviation"/>
                            <xul:menuitem value="acronym" label="Acronym"/>
                            <xul:menuitem value="address" label="Address"/>
                            <xul:menuitem value="cite" label="Citation"/>
                            <xul:menuitem value="samp" label="Sample"/>
                            <xul:menuitem value="var" label="Variable"/>
                            
                                                                                   
                                                                                                            
                        </xul:menupopup>
                    </xul:menulist>
                    <!--
                    
                    We should have a class list here really!! 
                    
                    <xul:menulist id="fontname">
                        <xul:menupopup  onpopuphiding="this.parentNode.parentNode.parentNode.parentNode.setStyle(this.parentNode);">
                            <xul:menuitem  value="0" label="Font"/>
                            <xul:menuitem value="Arial" label="Arial"/>
                            <xul:menuitem  value="Courier" label="Courier"/>
                            <xul:menuitem value="Times New Roman" label="Times New Roman"/>
                        </xul:menupopup>
                    </xul:menulist>
                    -->
                    <!--
                    <xul:menulist id="fontsize">
                        <xul:menupopup  onpopuphiding="this.parentNode.parentNode.parentNode.parentNode.setStyle(this.parentNode);"> >
                            <xul:menuitem  value="0" label="Size"/>
                            <xul:menuitem  value="1" label="1"/>
                            <xul:menuitem  value="2" label="2"/>
                            <xul:menuitem  value="3" label="3"/>
                            <xul:menuitem  value="4" label="4"/>
                            <xul:menuitem  value="5" label="5"/>
                            <xul:menuitem  value="6" label="6"/>
                            <xul:menuitem  value="7" label="7"/>
                          </xul:menupopup>
                    </xul:menulist>
                    
                    
                    
                    -->
                    <xul:toolbarbutton id="bold" tag="b"   checked="false" 
                        image="images/ed_format_bold.gif" 
                        style="-moz-appearance: none !important"
                        oncommand="this.parentNode.parentNode.parentNode.exec(this.getAttribute('id'),null);"/>
                    <xul:toolbarbutton id="italic" tag="i" checkState="0" image="images/ed_format_italic.gif" 
                      oncommand="this.parentNode.parentNode.parentNode.exec(this.getAttribute('id'),null);"/>
                    <xul:toolbarbutton id="strikethrough" tag="strike" checkState="0"   image="images/ed_format_strike.gif" 
                        oncommand="this.parentNode.parentNode.parentNode.exec(this.getAttribute('id'),null);"/>
                    <xul:toolbarbutton id="justifyleft" tag="div:left" checkState="0"   image="images/ed_align_left.gif" 
                        oncommand="this.parentNode.parentNode.parentNode.exec(this.getAttribute('id'),null);"/>
                    <xul:toolbarbutton id="justifycenter" tag="div:center"  checkState="0"  image="images/ed_align_center.gif" 
                        oncommand="this.parentNode.parentNode.parentNode.exec(this.getAttribute('id'),null);"/>
                        
                    <xul:toolbarbutton id="justifyright" tag="div:right" checkState="0"   image="images/ed_align_right.gif" 
                        oncommand="this.parentNode.parentNode.parentNode.exec(this.getAttribute('id'),null);"/>
                        
                    <xul:toolbarbutton id="justifyfull" tag="div:justify" checkState="0"   image="images/ed_align_justify.gif" 
                        oncommand="this.parentNode.parentNode.parentNode.exec(this.getAttribute('id'),null);"/>
                        
                    <xul:toolbarbutton id="insertorderedlist" tag="ol" checkState="0"   image="images/ed_list_num.gif" 
                        oncommand="this.parentNode.parentNode.parentNode.exec(this.getAttribute('id'),null);"/>
                        
                    <xul:toolbarbutton id="insertunorderedlist" tag="ul" checkState="0"   image="images/ed_list_bullet.gif" 
                        oncommand="this.parentNode.parentNode.parentNode.exec(this.getAttribute('id'),null);"/>
                        
                    <xul:toolbarbutton id="outdent" checkState="0"   image="images/ed_indent_less.gif" 
                        oncommand="this.parentNode.parentNode.parentNode.exec(this.getAttribute('id'),null);"/>
                        
                    <xul:toolbarbutton id="indent" checkState="0"   image="images/ed_indent_more.gif" 
                        oncommand="this.parentNode.parentNode.parentNode.exec(this.getAttribute('id'),null);"/>
                        
                                           
                     <xul:menulist id="styleblock" maxwidth="160">
                        <xul:menupopup  anonid="stylemenupopup"
                          onpopuphiding="this.parentNode.parentNode.parentNode.parentNode.setStyle(this.parentNode);">
                            <xul:menuitem value="span:" label="--Style--"/>
                                                                                                            
                        </xul:menupopup>
                    </xul:menulist>
                    
                    <xul:toolbarbutton id="urlPick"    popup="navPopup"  image="images/ed_link.gif"
                        oncommand="this.parentNode.parentNode.parentNode.showLinkPopup(this);"/>
             
                    <xul:toolbarbutton id="imagePick"  popup="imagePopup" image="images/ed_image.gif" 
                        oncommand="this.parentNode.parentNode.parentNode.showImgPopup(this);"/>
                  
                    <xul:toolbarbutton id="tablePick"  image="images/insert_table.gif" 
                        oncommand="this.parentNode.parentNode.parentNode.insertTable(this);"/>
                    
                    <xul:toolbarbutton id="specialChar" popup="specialChars" image="images/ed_spchars.gif"/>
                    
                    <xul:toolbarbutton id="formElement" popup="formElementPopup" image="images/ed_form.gif"/>
                    
                    
                    <xul:spacer height="5" flex="1"/>
            
            
                </xul:toolbar>
                <!-- the image editign toolbar! -->
                <xul:deck anonid="toolbarDeck">
                    
                    <xul:toolbar  anonid="editContextToolbar" height="26"> 
                        <xul:toolbarbutton  image="images/ed_up.gif" 
                            oncommand="this.parentNode.parentNode.parentNode.parentNode.activateParentContext();"/> 
                        <xul:toolbarbutton label="&lt;TD&gt;" anonid="defaultcontexttagname"
                            oncommand="this.parentNode.parentNode.parentNode.parentNode.activateContext();"/> 
                        <xul:spacer  flex="1"/>
                     </xul:toolbar>
                   
                    <!-- <img> -->
                    <xul:hbox anonid="editIMGToolbar" deckindexid="1">
                        <xul:toolbarbutton  image="images/ed_up.gif" 
                            oncommand="this.parentNode.parentNode.parentNode.parentNode.activateParentContext();"/> 
                        <xul:toolbarbutton label="&lt;IMG&gt;"
                            oncommand="this.parentNode.parentNode.parentNode.parentNode.activateContext();"/> 
                       <xul:toolbarbutton label="width"   />
                        <xul:textbox anonid="editIMGToolbar_width" value="" width="35"
                            onchange="this.parentNode.parentNode.parentNode.parentNode.attrChange(this);"
                            onkeyup="if(event.keyCode==13) this.parentNode.parentNode.parentNode.parentNode.attrChange(this);"/>
                        <xul:toolbarbutton label="height"   />
                        <xul:textbox anonid="editIMGToolbar_height" value="" width="35" 
                            onchange="this.parentNode.parentNode.parentNode.attrChange(this);"
                            onkeyup="if(event.keyCode==13) this.parentNode.parentNode.parentNode.parentNode.attrChange(this);"/>
                        
                        <xul:toolbarbutton label="align"   />
                        
                        <xul:menulist anonid="editIMGToolbar_align">
                            <xul:menupopup  
                              onpopuphiding="this.parentNode.parentNode.parentNode.parentNode.parentNode.attrChange(this.parentNode);">
                                <xul:menuitem value="" label="--Align--"/>
                                <xul:menuitem value="left" label="Left"/>
                                <xul:menuitem value="right" label="Right"/>
                                <xul:menuitem value="center" label="Center"/>
                                 <xul:menuitem value="top" label="Top"/>
                            </xul:menupopup>
                        </xul:menulist>
                        <xul:toolbarbutton label="border"  />
                        <xul:textbox value=""  anonid="editIMGToolbar_border" width="25"
                            onchange="this.parentNode.parentNode.parentNode.parentNode.attrChange(this);"
                            onkeyup="if(event.keyCode==13) this.parentNode.parentNode.parentNode.parentNode.attrChange(this);"/>
                       
                        <xul:toolbarbutton label="alt"    />
                        <xul:textbox anonid="editIMGToolbar_alt" value="" width="60"
                            onchange="this.parentNode.parentNode.parentNode.parentNode.attrChange(this);"
                            onkeyup="if(event.keyCode==13) this.parentNode.parentNode.parentNode.parentNode.attrChange(this);"/>
                       
                        <xul:toolbarbutton label="src"   />
                        <xul:textbox anonid="editIMGToolbar_src" value="" flex="1"
                            onchange="this.parentNode.parentNode.parentNode.parentNode.attrChange(this);"
                            onkeyup="if(event.keyCode==13) this.parentNode.parentNode.parentNode.parentNode.attrChange(this);"/>
                       
                        <xul:spacer height="5" />
                
                
                    </xul:hbox>
                    
                    <!-- <a> -->
                    <xul:hbox anonid="editAToolbar" deckindexid="2">
                        <xul:toolbarbutton  image="images/ed_up.gif" 
                            oncommand="this.parentNode.parentNode.parentNode.parentNode.activateParentContext();"/> 
                        <xul:toolbarbutton label="&lt;A&gt;"
                            oncommand="this.parentNode.parentNode.parentNode.parentNode.activateContext();"/> 
                        <xul:toolbarbutton label="name#" />
                        <xul:textbox anonid="editAToolbar_name" value="" width="60" 
                            onchange="this.parentNode.parentNode.parentNode.parentNode.attrChange(this);"
                            onkeyup="if(event.keyCode==13) this.parentNode.parentNode.parentNode.parentNode.attrChange(this);"/>
                        
                        <xul:toolbarbutton label="href"    />
                        
                        <xul:textbox anonid="editAToolbar_href" value="" flex="1"
                            onchange="this.parentNode.parentNode.parentNode.parentNode.attrChange(this);"
                            onkeyup="if(event.keyCode==13) this.parentNode.parentNode.parentNode.parentNode.attrChange(this);"/>
                        
                    </xul:hbox>
                    
                    
                    
                    <!-- <body> -->
                    <xul:toolbar anonid="editBODYToolbar" deckindexid="3">
                        
                        <xul:toolbarbutton label="&lt;BODY&gt;"
                            oncommand="this.parentNode.parentNode.parentNode.parentNode.activateContext();"/> 
                        <!-- <xul:toolbarbutton label="Document Title" />
                        <xul:textbox anonid="editBODYToolbar_title" value="" flex="1"
                            onchange="this.parentNode.parentNode.parentNode.parentNode.attrChange(this);"
                            onkeyup="if(event.keyCode==13) this.parentNode.parentNode.parentNode.parentNode.attrChange(this);"/>
                        -->
                
                    </xul:toolbar>
                    
                    <!-- <table> -->
                    <xul:toolbar anonid="editTABLEToolbar" deckindexid="4">
                        <xul:toolbarbutton  image="images/ed_up.gif" 
                            oncommand="this.parentNode.parentNode.parentNode.parentNode.activateParentContext();"/> 
                        <xul:toolbarbutton label="&lt;TABLE&gt;"
                            oncommand="this.parentNode.parentNode.parentNode.parentNode.activateContext();"/> 
                        <xul:toolbarbutton label="Rows" />
                        <xul:textbox anonid="editTABLEToolbar_rows" value="" width="35" 
                            onchange="this.parentNode.parentNode.parentNode.parentNode.attrChange(this);"
                            onkeyup="if(event.keyCode==13) this.parentNode.parentNode.parentNode.parentNode.attrChange(this);"/>
                            
                        <xul:toolbarbutton label="Cols" />
                        <xul:textbox anonid="editTABLEToolbar_cols" value="" width="35" 
                            onchange="this.parentNode.parentNode.parentNode.parentNode.attrChange(this);"
                            onkeyup="if(event.keyCode==13) this.parentNode.parentNode.parentNode.parentNode.attrChange(this);"/>
                        <xul:toolbarbutton label="Width" />
                        <xul:textbox anonid="editTABLEToolbar_width" value="" width="35" 
                            onchange="this.parentNode.parentNode.parentNode.parentNode.attrChange(this);"
                            onkeyup="if(event.keyCode==13) this.parentNode.parentNode.parentNode.parentNode.attrChange(this);"/>
                            
                        <xul:toolbarbutton label="Height" />
                        <xul:textbox anonid="editTABLEToolbar_height" value="" width="35" 
                            onchange="this.parentNode.parentNode.parentNode.parentNode.attrChange(this);"
                            onkeyup="if(event.keyCode==13) this.parentNode.parentNode.parentNode.parentNode.attrChange(this);"/>
                            
                        <xul:toolbarbutton label="Border"  />
                        <xul:textbox anonid="editTABLEToolbar_border" value="" width="35" 
                            onchange="this.parentNode.parentNode.parentNode.parentNode.attrChange(this);"
                            onkeyup="if(event.keyCode==13) this.parentNode.parentNode.parentNode.parentNode.attrChange(this);"/>
                        
                            
                    </xul:toolbar>
                    <!--      
                            cellspacing %Length;       #IMPLIED   spacing between cells 
                            cellpadding %Length;       #IMPLIED    spacing within cells -
                          -->
                     
                    <!-- <td> -->
                    <xul:toolbar anonid="editTDToolbar" deckindexid="5">
                        <xul:toolbarbutton  image="images/ed_up.gif" 
                            oncommand="this.parentNode.parentNode.parentNode.parentNode.activateParentContext();"/> 
                        <xul:toolbarbutton label="&lt;TD&gt;"
                            oncommand="this.parentNode.parentNode.parentNode.parentNode.activateContext();"/> 
                        <xul:toolbarbutton label="Width" />
                        <xul:textbox anonid="editTDToolbar_width" value="" width="35" 
                            onchange="this.parentNode.parentNode.parentNode.parentNode.attrChange(this);"
                            onkeyup="if(event.keyCode==13) this.parentNode.parentNode.parentNode.parentNode.attrChange(this);"/>
                            
                        <xul:toolbarbutton label="Height" />
                        <xul:textbox anonid="editTDToolbar_height" value="" width="35" 
                            onchange="this.parentNode.parentNode.parentNode.parentNode.attrChange(this);"
                            onkeyup="if(event.keyCode==13) this.parentNode.parentNode.parentNode.parentNode.attrChange(this);"/>
                            
                             
                        <xul:menulist anonid="editTDToolbar_align">
                            <xul:menupopup  
                              onpopuphiding="this.parentNode.parentNode.parentNode.parentNode.parentNode.attrChange(this.parentNode);">
                                <xul:menuitem value="" label="--Align--"/>
                                <xul:menuitem value="left" label="Left"/>
                                <xul:menuitem value="center" label="Center"/>
                                <xul:menuitem value="right" label="Right"/>
                                 <xul:menuitem value="justify" label="Justified"/>
                                 <xul:menuitem value="char"   label="Char"/>
                            </xul:menupopup>
                        </xul:menulist>
                        
                        <xul:menulist anonid="editTDToolbar_valign">
                            <xul:menupopup  
                              onpopuphiding="this.parentNode.parentNode.parentNode.parentNode.parentNode.attrChange(this.parentNode);">
                                <xul:menuitem value="" label="--VAlign--"/>
                                <xul:menuitem value="top" label="Top"/>
                                <xul:menuitem value="middle" label="Middle"/>
                                <xul:menuitem value="bottom" label="Bottom"/>
                                <xul:menuitem value="baseline" label="Baseline"/>
                                 
                            </xul:menupopup>
                        </xul:menulist>
                        
                        <!--<xul:toolbarbutton label="Row Span" />
                         <xul:textbox anonid="editTDToolbar_rowspan" value="" width="35" 
                            onchange="this.parentNode.parentNode.parentNode.parentNode.attrChange(this);"
                            onkeyup="if(event.keyCode==13) this.parentNode.parentNode.parentNode.parentNode.attrChange(this);"/>
                        -->
                        <xul:toolbarbutton label="Col Span" />
                        <xul:textbox anonid="editTDToolbar_colspan" value="" width="35" 
                            onchange="this.parentNode.parentNode.parentNode.parentNode.attrChange(this);"
                            onkeyup="if(event.keyCode==13) this.parentNode.parentNode.parentNode.parentNode.attrChange(this);"/>
                          
                            
                            
                    </xul:toolbar>
                    
                    <!-- <input> -->
                    <xul:hbox anonid="editINPUTToolbar" deckindexid="6">
                        <xul:toolbarbutton  image="images/ed_up.gif" 
                            oncommand="this.parentNode.parentNode.parentNode.parentNode.activateParentContext();"/> 
                        <xul:toolbarbutton label="&lt;INPUT&gt;"
                            oncommand="this.parentNode.parentNode.parentNode.parentNode.activateContext();"/> 
                        <xul:toolbarbutton label="name&amp;id=" />
                        <xul:textbox anonid="editINPUTToolbar_name" value="" width="60" 
                            onchange="this.parentNode.parentNode.parentNode.parentNode.attrChangeCore(this,true);"
                            onkeyup="if(event.keyCode==13) this.parentNode.parentNode.parentNode.parentNode.attrChangeCore(this,true);"/>
                        
                        <xul:toolbarbutton label="value=" />
                        
                        <xul:textbox anonid="editINPUTToolbar_value" value="" flex="1"
                            onchange="this.parentNode.parentNode.parentNode.parentNode.attrChange(this);"
                            onkeyup="if(event.keyCode==13) this.parentNode.parentNode.parentNode.parentNode.attrChange(this);"/>
                        <!-- should we include checked / default -->
                        
                    </xul:hbox>
                    
                    <!-- <input> -->
                    <xul:hbox anonid="editLABELToolbar" deckindexid="7">
                        <xul:toolbarbutton  image="images/ed_up.gif" 
                            oncommand="this.parentNode.parentNode.parentNode.parentNode.activateParentContext();"/> 
                        <xul:toolbarbutton label="&lt;LABEL&gt;"
                            oncommand="this.parentNode.parentNode.parentNode.parentNode.activateContext();"/> 
                        <xul:toolbarbutton label="for form element id=" />
                        <xul:textbox anonid="editLABELToolbar_for" value="" width="60" 
                            onchange="this.parentNode.parentNode.parentNode.parentNode.attrChange(this);"
                            onkeyup="if(event.keyCode==13) this.parentNode.parentNode.parentNode.parentNode.attrChange(this);"/>
                        
                        
                        <!-- should we include checked / default -->
                        
                    </xul:hbox>
                    <!-- <textarea> -->
                    <xul:hbox anonid="editTEXTAREAToolbar" deckindexid="8">
                        <xul:toolbarbutton  image="images/ed_up.gif" 
                            oncommand="this.parentNode.parentNode.parentNode.parentNode.activateParentContext();"/> 
                        <xul:toolbarbutton label="&lt;TEXTAREA&gt;"
                            oncommand="this.parentNode.parentNode.parentNode.parentNode.activateContext();"/> 
                        <xul:toolbarbutton label="name&amp;id==" />
                        <xul:textbox anonid="editTEXTAREAToolbar_name" value="" width="60" 
                            onchange="this.parentNode.parentNode.parentNode.parentNode.attrChangeCore(this,true);"
                            onkeyup="if(event.keyCode==13) this.parentNode.parentNode.parentNode.parentNode.attrChangeCore(this,true);"/>
                        <xul:toolbarbutton label="rows=" />
                        <xul:textbox anonid="editTEXTAREAToolbar_rows" value="" width="60" 
                            onchange="this.parentNode.parentNode.parentNode.parentNode.attrChange(this);"
                            onkeyup="if(event.keyCode==13) this.parentNode.parentNode.parentNode.parentNode.attrChange(this);"/>
                            
                        <xul:toolbarbutton label="cols=" />
                        <xul:textbox anonid="editTEXTAREAToolbar_cols" value="" width="60" 
                            onchange="this.parentNode.parentNode.parentNode.parentNode.attrChange(this);"
                            onkeyup="if(event.keyCode==13) this.parentNode.parentNode.parentNode.parentNode.attrChange(this);"/>
                        
                        <!-- should we include checked / default -->
                        
                    </xul:hbox>
                     <!-- <textarea> -->
                    <xul:hbox anonid="editSELECTToolbar" deckindexid="9">
                        <xul:toolbarbutton  image="images/ed_up.gif" 
                            oncommand="this.parentNode.parentNode.parentNode.parentNode.activateParentContext();"/> 
                        <xul:toolbarbutton label="&lt;SELECT&gt;"
                            oncommand="this.parentNode.parentNode.parentNode.parentNode.activateContext();"/> 
                        <xul:toolbarbutton label="name&amp;id=" />
                        <xul:textbox anonid="editSELECTToolbar_name" value="" width="60" 
                            onchange="this.parentNode.parentNode.parentNode.parentNode.attrChangeCore(this,true);"
                            onkeyup="if(event.keyCode==13) this.parentNode.parentNode.parentNode.parentNode.attrChangeCore(this,true);"/>
                        
                        
                        <!-- should we include checked / default -->
                        <xul:toolbarbutton label="value (eg. a=b,c=d,f,g,*c)" />
                        
                        <xul:textbox anonid="editINPUTToolbar_selectoptions" value="" flex="1"
                            onchange="this.parentNode.parentNode.parentNode.parentNode.setSelectOptions(this);"
                            onkeyup="if(event.keyCode==13) this.parentNode.parentNode.parentNode.parentNode.setSelectOptions(this);"/>
                        <!-- should we include checked / default -->
                    
                    </xul:hbox>
                    
                </xul:deck>
                
                
                 
                 
                <xul:textbox anonid="editor"/>
               <!--   <xul:button label="debug"  oncommand="this.parentNode.parentNode.debugAlert();"/>    -->
               
                <xul:hbox anonid="nodehbox">
                   
                   <xul:label anonid="tmpstatus" value="" onclick="alert('hello')"/> <!-- this is the temporary status window!!! -->
                   
                </xul:hbox>
            </xul:vbox>
            
            
            
             <xul:popupset>
              <xul:popup anonid="imagePick">
                <xul:menuitem label="image 1"/>
                <xul:menuitem label="image 2"/>
                <xul:menuitem label="image 3"/>
              </xul:popup>
            </xul:popupset>
        
        </content>
        
        <!-- ::::::::::::::::: INTERFACE ::::::::::::::::::::::::: -->
        <implementation>
            <property name="value" 
                        onset="this.update(val,false)"
                        onget="return this.fromEditor();"/>
         
            <property name="src" 
                        onset="this.updateSrc(val,false)"
                        onget="return this.url"/>
                        
          
          
            <constructor><![CDATA[
           
                var editor              = document.getAnonymousElementByAttribute(this, "anonid", "editor");
                this.debug              = 0;
                this.view               = 'Editor';
                this.command            = false;
                this.url                = this.getAttribute('src');
                this.viewUrl            = '';
                this.html               = ''; // the html!
                this._lastTag           = null;
                this._activeTags        = new Array();
                this._doc               = null; // will hold the editor docuemnt.
                this._timerToolbar      = null; //????
                this.editingNode        = false; // currently edited node. 
                this.image_urlbase      = '';  // base url for images.
                this.onLoadEventListener = null; 
                
                this.editToolbar =  document.getAnonymousElementByAttribute(this, "anonid", "editToolbar");
                
                this._nodeHbox      = document.getAnonymousElementByAttribute(this, "anonid", "nodehbox");
                this._tmpstatus      = document.getAnonymousElementByAttribute(this, "anonid", "tmpstatus");
                
                if (this.hasAttribute('value')) {       
                   
                    this.html = this.getAttribute("value");
                } else {
                    this.html = this.childnodes[0].value; // the inner stuff (maybe a CDATA element?
                    // or maybe htmlspecialchared?
                }
                var height = 300;
                if (this.hasAttribute('editorheight') &&  ((this.getAttribute('editorheight') * 1) > 1)) {
                     
                    height = this.getAttribute('editorheight')  * 1;
                }
                 var width = '100%';
                if (this.hasAttribute('editorwidth') &&  ((this.getAttribute('editorwidth') * 1) > 1)) {
                     
                    width = this.getAttribute('editorwidth')  * 1;
                }
                for(var i = 0;i < document.styleSheets.length; i++) {
                    var h = document.styleSheets.item(i).href;
                    if (!h.match(/HtmlEdit.css$/)) {
                        continue;
                    }
                    
                    this.image_urlbase = document.styleSheets.item(i).href.replace(/HtmlEdit.css$/, '');
                }
                
                
                var toolbars = new Array('editToolbar', 'toolbarDeck');
                for (var i =0; i < toolbars.length;i++) {
                    var node = document.getAnonymousElementByAttribute(this, "anonid", toolbars[i])
                    //alert(node);
                    this.replaceMenuImages(node);
                }
                
                
                
                var doc = new DOMParser().parseFromString("<iframe xmlns='http://www.w3.org/1999/xhtml' " + 
                           "  height='" + height + "'  width='" + width + "' src='"+ this.image_urlbase + "/blank.html' " + 
                            " flex='1' style='background: white;'></iframe>", 
                        'text/xml');
                doc = doc.firstChild;
                this.editor      = document.importNode(doc,true);
                 
                editor.parentNode.replaceChild(this.editor,editor);
                
                
                var _t = this;
                this.onLoadEventListener =   function() { _t.onload(); }
                window.addEventListener("load", this.onLoadEventListener , false);
                return;
                 
                
                ]]>
            </constructor>
            
            
            
               
           <method name="onload">
                <body><![CDATA[
                    
                   
                    /* remove onload handler so it is not fired up again.. */
                    if (!this.onLoadEventListener ) {
                        return;
                    }
                    window.removeEventListener("load",  this.onLoadEventListener , false);
                    this.onLoadEventListener  = false;
                    
                    
                  
                    
                    // now find all the images in the menu..
                    
                    
                
                    this._doc               = this.editor.contentWindow.document;
                    this.editor.contentWindow.document.designMode = "on";
                    
                    try {
                        this.editor.contentWindow.document.execCommand("undo", false, null);
                    }  catch (e) {
                        alert("There was a problem starting the editor:" + e);
                        return;
                    } 
                    this._doc.execCommand("useCSS", false, 0);  
                    
                    this.editor.contentWindow.document.body.innerHTML = this.html;
                    
                    // try and load a style sheet into the document..
                    // FIXME: this needs to be setable on the fly really...
                    
                    if (this.hasAttribute('stylesheet')) {
                        
                        var st = this._doc.createElement('link');
                        st.setAttribute('type', 'text/css');
                        st.setAttribute('rel', 'stylesheet');
                        st.setAttribute('href',this.getAttribute('stylesheet'));
                            // 'http://www.akbkhome.com/FlexyWiki/templates/images/master.css'
                        
                        var head = this._doc.createElement('head');
                        if (!this._doc.head) {
                            this._doc.body.parentNode.insertBefore(head, this._doc.body);
                            head.appendChild(st);
                        } else {
                            this._doc.head.appendChild(st);
                        }
                        var _t = this;
                        setTimeout(function() {
                            _t.updateStyleList();
                        }, 100);
                         
                    }
                    var st = this._doc.createElement('style');
                    st.appendChild(this._doc.createTextNode('table,td { border: 1px dashed #ccc; }'));
                    var head = this._doc.createElement('head');
                    if (!this._doc.head) {
                        this._doc.body.parentNode.insertBefore(head, this._doc.body);
                        head.appendChild(st);
                    } else {
                        this._doc.head.appendChild(st);
                    }
                    
                    var editor = this;
                    var _func = function (event) {
                             return editor._editorEvent(event);
                         }
                    var events = ["keydown", "keypress", "mousedown", "mouseup", "drag", "dragexit" ];
                    for (var i in events) {
                        this._doc.addEventListener(events[i], _func, true);
                    }

                    this.updateToolbar();
                
                    ]]>
                </body>
            </method>
            
            
             <method name="replaceMenuImages">
                <parameter name="node"/>
                <body><![CDATA[
                    if (node == null) {
                        return;
                    }
                    //alert(node.nodeName);
                    if (node.nodeType != 1) { // only deal with tags
                        return;
                    }
                    //if (node.getAttribute('image')) {
                    //    alert( node.getAttribute('image'));
                    //}
                    if (node.getAttribute('image') && node.getAttribute('image').match(/^images\//)) {
                        var old = node.getAttribute('image');
                        //alert('set new image to: ' + this.image_urlbase + old);
                        node.setAttribute('image', this.image_urlbase + old);
                        return;
                    }
                    if (!node.childNodes || !node.childNodes.length) {
                        return;
                    }
                    for (var i =0; i < node.childNodes.length; i++) {
                        this.replaceMenuImages(node.childNodes[i]);
                    }
                   ]]>
                </body>
            </method>
            
            
            
            
            
            <method name="updateStyleList">
                
                <body><![CDATA[
                    var rules =  false;
                    try {
                        var rules = this._doc.styleSheets.item(0).cssRules;
                    } catch (e) {
                        var _t = this;
                        setTimeout(function() {
                            _t.updateStyleList();
                        }, 100);
                        return;
                    }
                    var str = '';
                    var styles = new Array();
                    var testobj = new Object();
                    for (var i in rules) {
                        if (!rules[i].selectorText) {
                            continue;
                        }
                        str = str + "\n" + rules[i].selectorText;
                        var ar  = rules[i].selectorText.split(/,/);
                        for (var ii in ar) {
                            ar[ii] = ar[ii].replace(/^\s+/,'');
                            ar[ii] = ar[ii].replace(/\s+$/,'');
                            if (ar[ii].match(/\s+/)) {
                                continue;
                            }
                            if (ar[ii].substr(0,1) == '.') {
                                if (testobj[ar[ii]]) { 
                                    continue;
                                }
                                styles.push(ar[ii].replace(/./,''));
                                testobj[ar[ii]] = 1;
                            }
                        }
                        
                    }
                    styles.sort();
                    // <xul:menuitem value="pre" label="Formatted"/>
                    var stylePulldown = document.getAnonymousElementByAttribute(this, "anonid", "stylemenupopup");
                    for (var i in styles) {
                        var style = styles[i];
                        var mi = document.createElement('menuitem');
                        mi.setAttribute('value', 'span:'+style);
                        mi.setAttribute('label', '.'+style);
                        mi.setAttribute('tooltiptext', '.'+style);
                        stylePulldown.appendChild(mi);
                    }
                        
                    //alert(str);
                    //alert(styles); 
                    
                 
                    ]]>
                </body>
            </method>
            
            <method name="exec">
                <parameter name="cmd"/>
                <parameter name="value"/>
                <body><![CDATA[
                    // alert(cmd);
                    //alert(this.editor);
                    this.editor.contentWindow.document.execCommand(cmd,false,value);
                    // update the toolbar state after some time
                    var editor = this;
                    if (editor._timerToolbar) {
                        clearTimeout(this._timerToolbar);
                    }
                    editor._timerToolbar = setTimeout(function() {
                        editor.updateToolbar();
                        editor._timerToolbar = null;
                    }, 50);
                    ]]>
                </body>
            </method>
         
             <method name="setStyle">
                <parameter name="sel"/>
                <body><![CDATA[
                    if (sel.value != 0) {
                        var selected = sel.value;
                        
                        if (selected.match(/:/)) {
                            var ar = selected.split(/:/);
                            var selnode = this.getSelectedNode();
                            if (selnode) {
                                if (!ar[1].length) {
                                    selnode.removeAttribute('class');
                                } else {
                                    selnode.setAttribute('class',ar[1]);
                                }
                            } else {
                                alert('You must select a tag to associate style with');
                                 
                                /*
                                //alert('insert div with style!');
                                var sel = this.editor.contentWindow.getSelection();
                                var range = this._createRange(sel);
                                var newParent = this._doc.createElement('span');
                                
                                newParent.setAttribute('class',ar[1]);
                                //range.surroundContents( newParent );
                                newParent.appendChild(range.extractContents());range.insertNode(newParent);
                                */
                            }
                            
                        } else {
                        
                            this.editor.contentWindow.document.execCommand(
                                sel.attributes['id'].value, false, sel.value
                            );
                        }
                        sel.selectedIndex = 0;
                    }
                    var editor = this;
                    if (editor._timerToolbar) {
                        clearTimeout(this._timerToolbar);
                    }
                    editor._timerToolbar = setTimeout(function() {
                        editor.updateToolbar();
                        editor._timerToolbar = null;
                    }, 50);
                    ]]>
                 </body>
            </method>
            
             <method name="fromEditor">
                 <body><![CDATA[
                        /* what was this about? 
                        if (this._lastTag) {
                            this._lastTag.removeAttribute('htmleditor');
                            this._lastTag = null;
                        }
                        */
                        var preblock;
                        var preblocks;
                        var i;
                        var edoc = this.editor.contentWindow.document;
                        //alert(edoc);
                        preblocks = edoc.getElementsByTagName('pre');
                        
                        
                        /* replace <BR>'s in <PRE> blocks with \n's */
                        for(i=0;i<preblocks.length;i++) {
                           // alert(i);
                            var brs;
                            var j=0;
                            
                            while (brs = preblocks[i].getElementsByTagName('br')) {
                                if (!brs[j]) {
                                    break;
                                }
                                var tn = edoc.createTextNode("\n");
                                try {
                                    preblocks[i].replaceChild(tn,brs[j]);
                                } catch (e) {
                                    j++;
                                    continue;
                                }
                            }
                        }
                        
                        var html = this.editor.contentWindow.document.body.innerHTML;
                        //alert(html);
                        this.html = html;
                        
                        /* 
                        replace our base url with %%baseurl%% - not needed..
                        var re = new  RegExp("http://[a-z.]+"+baseurl,"g")
                        // replace {baseurl} with baseurl
                        this.html = html.replace(re, "%7BbaseURL%7D");
                        */
                        
                        // replace empty tags..
                        this.html = this.html.replace(/\<\>/g, '');
                        this.html = this.html.replace(/\<\/\>/g, '');
                        
                        // symbols to &# entries..
                        this.html = this.html.replace(/\xA9/i,    '&#169;');
                        this.html = this.html.replace(/\xAE/i,    '&#174;');
                        this.html = this.html.replace(/\u2122/i, '&#8482;');
                        this.html = this.html.replace(/\xA3/i,    '&#163;');
                        this.html = this.html.replace(/\u2122/i, '&#8482;');
                        this.html = this.html.replace(/\u2014/i, '&#8212;');
                        this.html = this.html.replace(/\u2026/i, '&#8230;');
                        this.html = this.html.replace(/\xF7/i,    '&#247;');
                        this.html = this.html.replace(/\xE1/i,    '&#225;');
                        this.html = this.html.replace(/\xA5/i,    '&#165;');
                        this.html = this.html.replace(/\u20AC/i, '&#8364;');
                        this.html = this.html.replace(/\u201C/i, '&#8220;');
                        this.html = this.html.replace(/\u201D/i, '&#8221;');
                        this.html = this.html.replace(/\u2022/i, '&#8226;');
                        this.html = this.html.replace(/\xB0/i,    '&#176;');
                        this.html = this.html.replace(/\x85/i,    '&#233;');
                        this.html = this.html.replace(/\xFA/i,    '&#250;');
                        
                        
                        
                        
                        
                        //alert(this.html);
                  
                        return this.html;
                        
                        ]]>
                 </body>
            </method>
            
    
            <method name="_editorEvent">
                <parameter name="ev"/>
                    <body><![CDATA[
   
                    var editor = this;
                    var keyEvent =  (ev.type == "keypress");
                    if (keyEvent) {
                        /*
                        for (var i in editor.plugins) {
                            var plugin = editor.plugins[i].instance;
                            if (typeof plugin.onKeyPress == "function") plugin.onKeyPress(ev);
                        }
                        */
                    }
                    if (keyEvent && ev.ctrlKey) {
                        var sel = null;
                        var range = null;
                        var key = String.fromCharCode(ev.charCode).toLowerCase();
                        var cmd = null;
                        var value = null;
                        switch (key) {
                            case 'a':
                           
                                // KEY select all
                                sel = this.editor.contentWindow.getSelection();
                                sel.removeAllRanges();
                                range = this._createRange();
                                range.selectNodeContents(this._doc.body);
                                sel.addRange(range);
                                ev.preventDefault();
                                ev.stopPropagation();
                            
                                break;
                
                            // simple key commands follow
                
                            case 'b': cmd = "bold"; break;
                            case 'i': cmd = "italic"; break;
                            case 'u': cmd = "underline"; break;
                            case 's': cmd = "strikethrough"; break;
                            case 'l': cmd = "justifyleft"; break;
                            case 'e': cmd = "justifycenter"; break;
                            case 'r': cmd = "justifyright"; break;
                            case 'j': cmd = "justifyfull"; break;
                            case 'z': cmd = "undo"; break;
                            case 'y': cmd = "redo"; break;
                            case 'v': cmd = "paste"; break;
                
                            case '0': cmd = "killword"; break;
                
                            // headings
                            case '1':
                            case '2':
                            case '3':
                            case '4':
                            case '5':
                            case '6':
                                cmd = "formatblock";
                                value = "h" + key;
                                 
                                break;
                        }
                        if (cmd) {
                            // execute simple command
                            try {
                                this._doc.execCommand(cmd, false, value);
                                ev.preventDefault();
                                ev.stopPropagation();
                            } catch(e) { } // copy paste - allowed by default!?
                                
                             
                        }
                    }
                   
                    // update the toolbar state after some time
                    if (editor._timerToolbar) {
                        clearTimeout(this._timerToolbar);
                    }
                    editor._timerToolbar = setTimeout(function() {
                        editor.updateToolbar();
                        editor._timerToolbar = null;
                    }, 50);
                };


              ]]>
                 </body>
            </method>
             <method name="_isContextEnabled">
                <parameter name="context"/>
                  <body><![CDATA[
                    // is this button enabled?
                    
                    var ancestors = this.getAllAncestors();
                    var inContext = false;
                    var align = false;
                    if (context.match(':')) {
                        var ar = context.split(':');
                        context = ar[0];
                        align = ar[1];
                    }
                    
                    for (var k in ancestors) {
                        if (!ancestors[k]) {
                            // this happens if our top level is not a node.!
                            continue;
                        }
                       // this._tmpstatus.setAttribute('value', this._tmpstatus.getAttribute('value') + 
                       //   '<'+ ancestors[k].tagName.toLowerCase() + '> ');
                        
                        
                        
                        
                        if (ancestors[k].tagName.toLowerCase() == context) {
                            if (align) {
                                if (ancestors[k].hasAttribute('align') && 
                                    (ancestors[k].getAttribute('align').toLowerCase() == align)) {
                                    inContext = true;
                                }
                            } else {
                                inContext = true;
                            }
                            
                        }
                    }
                    return inContext;
                    
                    ]]>
                 </body>
            </method>
             
               
             <method name="updateToolbar">
               <body><![CDATA[
                     
                    // wipe out the children of the nodeHbox
                    
                    for(var i = this._nodeHbox.childNodes.length-1; i > -1;i--) {
                        this._nodeHbox.removeChild( this._nodeHbox.childNodes[i]);
                    }
                    
                    
                    //this._tmpstatus.setAttribute('value','');
                    var ancestors = this.getAllAncestors();
                    var lastlab = null;
                    var firststyle = '';
                    var pos = 0;
                    for (var k in ancestors) {
                        pos++;
                        if (!ancestors[k]) {
                            // this happens if our top level is not a node.
                            continue;
                        }
                        if (ancestors[k].hasAttribute('class') && !firststyle) {
                            firststyle = ancestors[k].getAttribute('class');
                        }
                            
                        
                        var lab = document.createElement('label');
                        lab.setAttribute('value','<'+ ancestors[k].tagName.toLowerCase() + '> ' );
                        if (pos == 1){
                            lab.setAttribute('style','font-weight: bold' );
                        }
                        lab.associatedNode = ancestors[k];
                        
                        // add callback for pressing label item.
                        this._nodeHbox.insertBefore(lab,lastlab);
                        var _t = this;
                        var _node = ancestors[k];
                        var _lab = lab;
                        var _func = function() {
                            _t.selectNode(this);
                        }
                        lab.addEventListener('click', _func, true);
                        
                        lastlab = lab;
                    }
                    
                    var ml = false;
                    for (var i = 0; i < this.editToolbar.childNodes.length; i++) {
                        if (this.editToolbar.childNodes[i].tagName == 'xul:menulist') {
                            ml = this.editToolbar.childNodes[i];
                            continue;
                        }
                        if (this.editToolbar.childNodes[i].tagName != 'xul:toolbarbutton') {
                            continue;
                        }
                        
                        if (!this.editToolbar.childNodes[i].hasAttribute('tag')  ) {
                            continue;
                        }
                        
                        var enabled = this._isContextEnabled(this.editToolbar.childNodes[i].getAttribute('tag'));
                              
                        if (enabled) {
                            this.editToolbar.childNodes[i].setAttribute('checked', 'true');
                        } else {
                            this.editToolbar.childNodes[i].setAttribute('checked', 'false');
                        }
                         
                    }
                    //style - default to first item.
                    //ml.setAttribute('value',ml.childNodes[0].childNodes[0].getAttribute('label'));
                    ml.selectedIndex = 0;
                    for (var j = 0; j < ml.childNodes[0].childNodes.length; j++) {
                        var mlitem = ml.childNodes[0].childNodes[j];
                        if (!mlitem.getAttribute('value')) { 
                            continue;
                        }
                        
                        if (this._isContextEnabled(mlitem.getAttribute('value'))) {
                            
                            ml.selectedIndex = j;//setAttribute('value',mlitem.getAttribute('label'));
                            break;
                        }
                    }
                    
                    // update stylebar..
                    //alert(firststyle);
                    var stylePulldown = document.getAnonymousElementByAttribute(this, "anonid", "stylemenupopup");
                    if (!firststyle.length) {
                        stylePulldown.selectedIndex = 0;
                    } else {
                        //alert(stylePulldown.childNodes[1].getAttribute('value') );
                        for (var j=0; j < stylePulldown.childNodes.length; j++) {
                            if (stylePulldown.childNodes[j].getAttribute('value') == ('span:'+firststyle)) {
                                stylePulldown.parentNode.selectedIndex = j;
                                break;
                            }
                        }
                    }
                    this.showContextBar(ancestors);
                    
                 ]]>
                 </body>
            </method>
            
            <method name="getToolbarItemByName">
                <parameter name="name"/>
                <body><![CDATA[
                    for (var i = 0; i < this.editToolbar.childNodes.length; i++) {
                        try {
                            
                            
                            if (this.editToolbar.childNodes[i].getAttribute('id') == name ) {
                                return this.editToolbar.childNodes[i];
                            }
                        } catch (e) { } // ignore tryign to get attributes of non nodes..
                    }
                    return null;
                  ]]>
               </body>
            </method>
    
            <method name="getAllAncestors">
               <body><![CDATA[
    
                    // Returns an array with all the ancestor nodes of the selection.
                    // if the selected item is not a single node, the first item will be false.
                    
                    
                    var p = this.getSelectedNode();
                    var a = new Array();
                    if (!p) {
                        a.push(p); // push blank onto stack..
                        p = this.getParentElement();
                    }
                    
                    
                    while (p && (p.nodeType == 1) && (p.tagName.toLowerCase() != 'body')) {
                        a.push(p);
                        p = p.parentNode;
                    }
                    a.push(this._doc.body);
                    return a;
                     ]]>
                 </body>
            </method>
            
            <method name="getSelectedNode">
                <body><![CDATA[
        
                    var sel = this.editor.contentWindow.getSelection();
                    var range = this._createRange(sel);
                    var ar = range.endContainer.childNodes;
                    if (!ar.length) {
                        ar = range.commonAncestorContainer.childNodes;
                        //alert(ar.length);
                    }
                    var nodes = new Array();
                    var other_nodes = new Array();
                    var has_other_nodes = false;
                    for (var i=0;i<ar.length;i++) {
                        if ((ar[i].nodeType == 3) && (!ar[i].data.length)) { // empty text ? 
                            continue;
                        }
                        // fullly contained node.
                        if (range.intersectsNode(ar[i]) && range.compareNode(ar[i]) == 3) {
                            nodes.push(ar[i]);
                            continue;
                        }
                        
                        // probably selected..
                        if ((ar[i].nodeType == 1) && range.intersectsNode(ar[i]) && (range.compareNode(ar[i]) > 0)) {
                            other_nodes.push(ar[i]);
                            continue;
                        }
                        if (!range.intersectsNode(ar[i]) || (range.compareNode(ar[i]) == 0))  {
                            continue;
                        }
                        
                        
                        has_other_nodes = true;
                    }
                    if (!nodes.length && other_nodes.length) {
                        nodes= other_nodes;
                    }
                    if (has_other_nodes || !nodes.length || (nodes.length > 1)) {
                        return false;
                    }
                    return nodes[0];
                    
                   ]]>
                </body>
            </method> 
                
            <method name="getParentElement">
               <body><![CDATA[
                    // Returns the deepest node that contains both endpoints of the selection.
                
                    var sel = this.editor.contentWindow.getSelection();
                    var range = this._createRange(sel);
                     
                    try {
                        var p = range.commonAncestorContainer;
                        while (p.nodeType == 3) { // text node
                            p = p.parentNode;
                        }
                        return p;
                    } catch (e) {
                        return null;
                    }
                    
                    ]]>
                 </body>
            </method>
            
            
          <method name="_createRange">
               <parameter name="sel"/>
               <body><![CDATA[
                    // this has strange effects when using with 
                    // top toolbar - not sure if it's a great idea.
                    //this.editor.contentWindow.focus();
                    if (typeof sel != "undefined") {
                        try {
                            return sel.getRangeAt(0);
                        } catch(e) {
                            return this._doc.createRange();
                        }
                    } else {
                        return this._doc.createRange();
                    }
                   ]]>
             </body>
            </method>
        
    
          <method name="showImgPopup">
                <parameter name="element"/>
                  
               <body><![CDATA[
     
                var picker = this.getAttribute('imagepopup');
                if (!picker) {
                    alert('no imagepopup attribute has been set');
                    return;
                }
                var popup = document.getElementById(picker);
                
                var xCoord = element.boxObject.x;

                var yCoord = element.boxObject.y + element.boxObject.height;
                var _tt = this;
                var _func = null;
                _func = function(e) {
                    _tt.addImageEvent(e,_tt,_func);
                }
                
                for (var i=0; i < popup.childNodes.length; i++ ) {
                    popup.childNodes[i].addEventListener("command",  _func , false);
                }
                //popup.editor = this;
                popup.showPopup(element, xCoord, yCoord, "bottomleft", "topleft");
                
                 
            ]]>
             </body>
            </method>

            <method name="addImageEvent">
                <parameter name="e"/>
                <parameter name="tt"/>
                <parameter name="f"/>
                <body><![CDATA[
                    var picker = tt.getAttribute('imagepopup');
                    
                    var popup = document.getElementById(picker);
                    //var _func = this.addImageEvent;
                    //var _func = this.addImageEvent;
                    for (var i=0; i < popup.childNodes.length; i++ ) {
                        popup.childNodes[i].removeEventListener("command",  f , false);
                    }
                    //alert(e.target.getAttribute('imagesrc'));
                    //alert(tt.tagName);
                     
                    tt.exec('insertimage',e.target.getAttribute('imageurl') );
                  
            ]]>
             </body>
            </method>
    
    
            <method name="showLinkPopup">
                <parameter name="element"/>
                  
               <body><![CDATA[
                var sel = this.editor.contentWindow.getSelection();
                
                var range = this._createRange(sel);
                var existing = this.getHTML(range.cloneContents(), false, this);
                
                
                if (!existing.length) {
                    alert('no text selected for the link');
                    return;
                }
                
                var picker = this.getAttribute('linkpopup');
                if (!picker) {
                    alert('no linkpopup attribute has been set');
                    return;
                }
                var popup = document.getElementById(picker);
                var xCoord = element.boxObject.x;
                var yCoord = element.boxObject.y + element.boxObject.height;
                var _tt = this;
                var _func = null;
                _func = function(e) {
                    _tt.addLinkEvent(e,_tt,_func);
                }
                
                for (var i=0; i < popup.childNodes.length; i++ ) {
                    popup.childNodes[i].addEventListener("command",  _func , false);
                }
                
                popup.showPopup(element, xCoord, yCoord, "bottomleft", "topleft");
                
                 
            ]]>
             </body>
            </method>
         

            <method name="addLinkEvent">
                <parameter name="e"/>
                <parameter name="tt"/>
                <parameter name="f"/>
                <body><![CDATA[
                    var picker = tt.getAttribute('linkpopup');
                    
                    var popup = document.getElementById(picker);
                    
                    for (var i=0; i < popup.childNodes.length; i++ ) {
                        popup.childNodes[i].removeEventListener("command",  f , false);
                    }
                    var url = e.target.getAttribute('url');
                    if (url == 'pick:') {
                        url =  prompt("Enter the url:"); 
                    }
                    if (url == null) {
                        return;
                    }
                    if (!url) {
                        alert('no url to insert?' + url);
                        return;
                    }
                    
                    
                    tt.exec('createlink',url );
                  
            ]]>
             </body>
            </method>

            <method name="htmlEncode">
              <parameter name="str"/>
            
                  <body><![CDATA[
            
                     
                    // we don't need regexp for that, but.. so be it for now.
                    str = str.replace(/&/ig, "&amp;");
                    str = str.replace(/</ig, "&lt;");
                    str = str.replace(/>/ig, "&gt;");
                    str = str.replace(/\x22/ig, "&quot;");
                    // \x22 means '"' -- we use hex reprezentation so that we don't disturb
                    // JS compressors (well, at least mine fails.. ;)
                    return str;
                    ]]>
             </body>
            </method> 
            <method name="needsClosingTag">
              <parameter name="el"/>
                  <body><![CDATA[
                       
                        var closingTags = " head script style div span tr td tbody table em strong font a title ";
                        return (closingTags.indexOf(" " + el.tagName.toLowerCase() + " ") != -1);
                         ]]>
                </body>
            </method> 
            
            <method name="fillToolbar">
                <parameter name="prefix"/>
                <parameter name="el"/>
                <parameter name="editable"/>
                  <body><![CDATA[
                        // blank out tolbar
                        var bar = document.getAnonymousElementByAttribute(this, "anonid", prefix);
                        for (var i = 0;i < bar.childNodes.length;i++) {
                            try {
                                if (bar.childNodes[i].nodeType != 1) {
                                    continue;
                                }
                                var cname_ar = bar.childNodes[i].getAttribute('anonid').split(/_/);
                                
                                if (cname_ar[0] != prefix) {
                                    continue;
                                }
                                bar.childNodes[i].value= '';
                                if (!editable) {
                                    bar.childNodes[i].setAttribute('disabled',"true");
                                } else { 
                                    bar.childNodes[i].removeAttribute('disabled');
                                }
                                
                            } catch(e) { 
                                alert(bar.childNodes[i] + ' ' +e)
                            }
                        }
                        var msg = '';
                        // now fill in with the details of this one..
                        for (var i = 0; i < el.attributes.length; ++i) {
                            var a = el.attributes.item(i);
                            
                            var name = a.nodeName.toLowerCase();
                            var msg = msg + ' ' + a.nodeName + '=' + a.nodeValue;
                            var tb = document.getAnonymousElementByAttribute(this, "anonid", prefix+ '_'+name);
                            if (!tb) {
                                //alert('missing ' + prefix+ '_'+name);
                                continue;
                            }
                            //alert('set:' + prefix+ '_' + name + '=' + a.nodeValue);
                            tb.value =  a.nodeValue;
                        }
                        
                        
                        //alert(msg);
                       ]]>
                </body>
            </method>
            
            <method name="attrChange">
                <parameter name="obj"/>
                  <body><![CDATA[
                        this.attrChangeCore(obj, false);
                          ]]>
                </body>
            </method>  
            
            
            <method name="setSelectOptions">
                <parameter name="obj"/>
                  <body><![CDATA[
                        this.attrChangeCore(obj, false);
                        
                        var value = obj.value;
                        var opts = value.split(/,/);
                        var optsAr = new Array();
                        var defaultV = "";
                        for(var i=0; i < opts.length; i++) {
                            
                            opt = opts[i];
                            var isDefault = false;
                            if (opt.substr(0,1)  == "*") {
                                var isDefault = true;
                                opt = opt.substr(1);
                            }
                            
                            
                            var osplit=opt.split(/=/);
                            if (osplit.length > 1) {
                                optsAr[osplit[0]] = osplit[1];
                                if (isDefault) {
                                    defaultV = osplit[0];
                                }
                            } else {
                                optsAr[opt] = opt;
                                if (isDefault) {
                                    defaultV = opt;
                                }
                            }
                        
                        }
                        // now we have all the 
                        selNode = this.editingNode;
                        // remove all the children
                        for (var i=selNode.childNodes.length-1; i > -1; i--) {
                            selNode.removeChild(selNode.childNodes[i]);
                        }
                        for (var p in optsAr) {
                            var option = this._doc.createElement("option");
                            option.setAttribute('value', p);
                            if (defaultV == p) {
                                option.setAttribute('selected', 'selected');
                            }
                            option.appendChild(this._doc.createTextNode(optsAr[p]));
                            selNode.appendChild(option);
                        }
                        
                
                
                
                
                ]]></body>
            </method>  
            
            <method name="attrChangeCore">
                <parameter name="obj"/>
                <parameter name="withId"/>
                  <body><![CDATA[
                        
                        selNode = this.editingNode;
                        var namebits =obj.getAttribute('anonid').split(/_/);
                        var key = namebits[1];
                        var value = obj.value;
                        
                        // resize table
                        if ((selNode.tagName.toUpperCase() == 'TABLE') &&
                                ((key == 'rows') || (key == 'cols'))) {
                                
                            // adjust table col/rows
                            if (!this.adjustTableSize(selNode,key,value)) {
                                var ar = new Array();
                                ar[0] = selNode;
                                this.showContextBar(ar);
                                return;
                            }
                            
                        }
                        // change colspan on a td.
                        if ((selNode.tagName.toUpperCase() == 'TD') && (key == 'colspan')) {
                                
                            // adjust table col/rows
                            if (!this.adjustTableSize(selNode,key,value)) {
                                var ar = new Array();
                                ar[0] = selNode;
                                this.showContextBar(ar);
                                return;
                            }
                        }
                        
                        if (!value.length) {
                            selNode.removeAttribute(key);
                            if (withId) {
                                selNode.removeAttribute("id");
                            }
                            return;
                        }
                        if (withId) {
                            selNode.setAttribute("id", value) ;
                        }
                        selNode.setAttribute(key, value) ;
                         
                       ]]>
                </body>
            </method> 
            
           
                 
            <method name="selectNode">
                <parameter name="lab"/>
                  <body><![CDATA[
                        // unbold everything..
                        for (var i = 0;i < lab.parentNode.childNodes.length;i++) {
                            lab.parentNode.childNodes[i].setAttribute('style', '');
                        }
                        //alert(lab.getAttribute('value') + lab.associatedNode.tagName );
                        lab.setAttribute('style', 'font-weight: bold');
                        
                        // now lets try and select the contents.!
                        
                        
                        var sel = this.editor.contentWindow.getSelection();
                        var range = this._doc.createRange();
                        //range.selectNodeContents(lab.associatedNode);
                        range.selectNode(lab.associatedNode);
                        //(collapsed) && 
                        //range.collapse(0);
                        sel.removeAllRanges();
                        sel.addRange(range);
                        
                        
                        
                        var ar = new Array();
                        ar[0] = lab.associatedNode;
                        this.showContextBar(ar);
                        // todo : update status bar (show bold / italic on off as if in tree..
                        
                       ]]>
                </body>
            </method> 
            
            
            
            <method name="showContextBar">
                <parameter name="ancestors"/>
                <body><![CDATA[
                    
                    var showNode = this._doc.body;
                    var editable = true;
                
                    // turn them all off by default.. (by default each one just needs to show the context bar..
                    if (!ancestors  || !ancestors[0]) {
                        
                        
                        editable = false;
                        if (!ancestors  || !ancestors[1]) {
                            showNode = this._doc.body;
                            editable = false;
                        }
                        showNode = ancestors[1];
                    } else {
                        showNode = ancestors[0];
                    }
                    
                    var tagname = "edit" + showNode.tagName.toUpperCase()  + "Toolbar";
                    if (document.getAnonymousElementByAttribute(this, "anonid", tagname)) {
                        // flip to right deck.
                        var indexid = document.getAnonymousElementByAttribute(this, "anonid", tagname).getAttribute('deckindexid');
                        document.getAnonymousElementByAttribute(this, "anonid", "toolbarDeck").setAttribute("selectedIndex",indexid);
                        
                        this.fillToolbar(tagname, showNode,editable);
                        // turn off..
                        document.getAnonymousElementByAttribute(this, "anonid", tagname).setAttribute('htmledit_editable', editable);
                        this.editingNode = showNode;
                        return;
                    }
                    this.editingNode = showNode;
                    document.getAnonymousElementByAttribute(this, "anonid", "defaultcontexttagname").setAttribute('label', 
                        '<' + showNode.tagName.toUpperCase() + '>');
                    document.getAnonymousElementByAttribute(this, "anonid", "toolbarDeck").setAttribute("selectedIndex",'0');
                    ]]>
                </body>
            </method>
            
            
            <method name="getHTML">
              <parameter name="root"/>
              <parameter name="outputRoot"/>
              <parameter name="editor"/>
                  <body><![CDATA[
            
            
                // getHTML is used by the link adding to check if there's any content.!
            
                var html = "";
                switch (root.nodeType) {
                    case 1: // Node.ELEMENT_NODE
                    case 11: // Node.DOCUMENT_FRAGMENT_NODE
                        var closed;
                        var i;
                        var root_tag = (root.nodeType == 1) ? root.tagName.toLowerCase() : '';
                        
                        if (outputRoot) {
                            closed = (!(root.hasChildNodes() || this.needsClosingTag(root)));
                            html = "<" + root.tagName.toLowerCase();
                            var attrs = root.attributes;
                            for (i = 0; i < attrs.length; ++i) {
                                var a = attrs.item(i);
                                if (!a.specified) {
                                    continue;
                                }
                                var name = a.nodeName.toLowerCase();
                                if (/_moz|contenteditable|_msh/.test(name)) {
                                    // avoid certain attributes
                                    continue;
                                }
                                var value;
                                if (name != "style") {
                                   
                                    // Using Gecko the values of href and src are converted to absolute links
                                    // unless we get them using nodeValue()
                                    if (typeof root[a.nodeName] != "undefined" && name != "href" && name != "src") {
                                        value = root[a.nodeName];
                                    } else {
                                        value = a.nodeValue;
                                         
                                    }
                                } else { // IE fails to put style in attributes list
                                    // FIXME: cssText reported by IE is UPPERCASE
                                    value = root.style.cssText;
                                }
                                if (/(_moz|^$)/.test(value)) {
                                    // Mozilla reports some special tags
                                    // here; we don't need them.
                                    continue;
                                }
                                html += " " + name + '="' + value + '"';
                            }
                            html += closed ? " />" : ">";
                        }
                        
                        for (i = root.firstChild; i; i = i.nextSibling) {
                            html += this.getHTML(i, true, editor);
                        }
                        if (outputRoot && !closed) {
                            html += "</" + root.tagName.toLowerCase() + ">";
                        }
                        break;
                    case 3: // Node.TEXT_NODE
                        // If a text node is alone in an element and all spaces, replace it with an non breaking one
                        // This partially undoes the damage done by moz, which translates '&nbsp;'s into spaces in the data element
                        if ( !root.previousSibling && !root.nextSibling && root.data.match(/^\s*$/i) ) {
                            if (root.data.length) {
                                html = '&nbsp;';
                            }
                        } else {
                            html = this.htmlEncode(root.data);
                        }
                        break;
                    case 8: // Node.COMMENT_NODE
                        html = "<!--" + root.data + "-->";
                        break;        // skip comments, for now.
                }
                return html;
             
                  ]]>
             </body>
            </method> 
             
         
            <method name="debugAlert">
                <body><![CDATA[
                 
                        return;
                    var p = this.getSelectedNode();
                    alert(p);
                    if (p) {
                         alert(p.tagName);
                    }
                    var ar = this.getAllAncestors();
                    str = '';
                    for (var i=0; i< ar.length;i++) {
                        str = str + ' ' + ar[i].tagName;
                    }
                    alert(str);
                    ]]>
                </body>
            </method>
              
            <method name="insertTable">
                <body><![CDATA[
          
                    var sel = this.editor.contentWindow.getSelection();
                    var range = this._createRange(sel);
                    if (this.getHTML(range.cloneContents(), false, this).length) {
                        alert('You must not have anything selected to add a table');
                        return;
                    }
                    // create the table element
                    var table = this._doc.createElement("table");
                    table.setAttribute('width', '100%');
                    //table.setAttribute('border', '1');
                    
                    
                    // assign the given arguments
  
                    var tr = this._doc.createElement("tr");
                    table.appendChild(tr);
                    var td = this._doc.createElement("td");
                    tr.appendChild(td);
                    //should we add a child element?
                    td.appendChild(this._doc.createTextNode("Table Contents"));
                    this.insertNodeAtSelection(table);
                    
                    // select the table
                    
                    range.selectNode(table);
                    sel.removeAllRanges();
                    sel.addRange(range);
                    this.updateToolbar();
                    
                    
                  ]]>
                </body>
            </method>

            <method name="insertSymbol">
               <parameter name="Sender"/>
               <body><![CDATA[
               sel = this.editor.contentWindow.getSelection();
               range = sel.getRangeAt(0);
               range.deleteContents();
               //alert(Sender.getAttribute('label'));
               
               range.insertNode(this._doc.createTextNode(Sender.getAttribute('label')));

            ]]>
             </body>
            </method>

              <method name="insertFormElement">
               <parameter name="fromMenuItem"/>
               <body><![CDATA[
              
                    var sel = this.editor.contentWindow.getSelection();
                    var range = this._createRange(sel);
                    if (this.getHTML(range.cloneContents(), false, this).length) {
                        alert('You must not have anything selected to add an input element');
                        return;
                    }
                    // create the table element
                    
                    var lab = fromMenuItem.getAttribute('label');
                    var eToInsert;
                    switch (lab) {
                        case "form":
                            eToInsert= this._doc.createElement("form");
                            break;
                            
                        case "input: text":
                            eToInsert= this._doc.createElement("input");
                            eToInsert.setAttribute("type", "text");
                            break;
                            
                        case "input: checkbox":
                            eToInsert= this._doc.createElement("input");
                            eToInsert.setAttribute("type", "checkbox");
                            break;    
                            
                        case "input: radio":
                            eToInsert= this._doc.createElement("input");
                            eToInsert.setAttribute("type", "radio");
                            break;    
                            
                        case "input: password":
                            eToInsert= this._doc.createElement("input");
                            eToInsert.setAttribute("type", "password");
                            break; 
                            
                        case "textarea":
                            eToInsert= this._doc.createElement("textarea");
                            break; 
                            
                        case "label":
                            eToInsert= this._doc.createElement("label");
                            eToInsert.appendChild(this._doc.createTextNode("Input Label"));
                            break; 
                            
                        case "select":
                            eToInsert= this._doc.createElement("select");
                            eToInsert.setAttribute("selectoptions", '=--Please Select--');
                            var opt = this._doc.createElement("option");
                            opt.appendChild(this._doc.createTextNode("--Please Select--"));
                            eToInsert.appendChild(opt);
                            break;      
                            
                        default:
                            alert("unknown form element type to insert!");
                            return;
                            
                        
                    }
                    
                    
                   
                     
                    this.insertNodeAtSelection(eToInsert);
                    
                    // select the table
                    
                    range.selectNode(eToInsert);
                    sel.removeAllRanges();
                    sel.addRange(range);
                    this.updateToolbar();
            
            
            
            ]]>
             </body>
            </method>
            
            
            <method name="activateContext">
                <body><![CDATA[
                    var sel = this.editor.contentWindow.getSelection();
                    var range = this._createRange(sel);
                    range.selectNode(this.editingNode);
                    sel.removeAllRanges();
                    sel.addRange(range);
                    this.updateToolbar();
                ]]>
                </body>
            </method>     
            
             <method name="activateParentContext">
                <body><![CDATA[
                    var sel = this.editor.contentWindow.getSelection();
                    var range = this._createRange(sel);
                    range.selectNode(this.editingNode.parentNode);
                    sel.removeAllRanges();
                    sel.addRange(range);
                    this.updateToolbar();
                ]]>
                </body>
            </method>   
             <method name="insertNodeAtSelection">
                 <parameter name="toBeInserted"/>
                <body><![CDATA[
             
                    var sel = this.editor.contentWindow.getSelection();
                    var range = this._createRange(sel);
                    
                    // remove the current selection
                    sel.removeAllRanges();
                    range.deleteContents();
                    var node = range.startContainer;
                    var pos = range.startOffset;
                    switch (node.nodeType) {
                        case 3: // Node.TEXT_NODE
                            // we have to split it at the caret position.
                            if (toBeInserted.nodeType == 3) {
                                // do optimized insertion
                                node.insertData(pos, toBeInserted.data);
                                range = this._createRange();
                                range.setEnd(node, pos + toBeInserted.length);
                                range.setStart(node, pos + toBeInserted.length);
                                sel.addRange(range);
                            } else {
                                node = node.splitText(pos);
                                var selnode = toBeInserted;
                                if (toBeInserted.nodeType == 11 /* Node.DOCUMENT_FRAGMENT_NODE */) {
                                    selnode = selnode.firstChild;
                                }
                                node.parentNode.insertBefore(toBeInserted, node);
                                this.selectNodeContents(selnode);
                                this.updateToolbar();
                            }
                            break;
                            
                        case 1: // Node.ELEMENT_NODE
                            var selnode = toBeInserted;
                            if (toBeInserted.nodeType == 11 /* Node.DOCUMENT_FRAGMENT_NODE */) {
                                selnode = selnode.firstChild;
                            }
                            node.insertBefore(toBeInserted, node.childNodes[pos]);
                            this.selectNodeContents(selnode);
                            this.updateToolbar();
                            break;
                    }
                  ]]>
                </body>
            </method>
            <method name="selectNodeContents">
                <parameter name="node"/>
                <parameter name="pos"/>
                <body><![CDATA[
               
                    //this.focusEditor();
                    //this.forceRedraw();
                    var collapsed = (typeof pos != "undefined");
                    var sel = this.editor.contentWindow.getSelection();
                    var range = this._createRange(sel);
                    
                    range.selectNodeContents(node);
                    (collapsed) && range.collapse(pos);
                    sel.removeAllRanges();
                    sel.addRange(range);
      
                  ]]>
                </body>
            </method>
            <method name="adjustTableSize">
                <parameter name="tablenode"/>
                <parameter name="key"/>
                <parameter name="value"/>
                <body><![CDATA[
                
                
                    // return false on error (reset entry)
                    // true on succes
                
                    
                    value = value  * 1;
                    
                    if (key == 'rows') {
                        // we ignore row span here!!!
                    
                        var rows = 0;
                        for (var i=0;i < tablenode.childNodes.length;i++) {
                            if (tablenode.childNodes[i].tagName.toLowerCase() == 'tr') {
                                rows++;
                            }
                        }
                        if (value == rows) {
                            return true; // nothing changed..?
                        }
                        if (value < rows) { 
                            if (!confirm('are you sure you want to remove the last ' + (rows - value) + ' rows?')) {
                                return false; // eak.. you end up the wrong value in the toolbar!
                            }
                            for (var i=0;i <  (rows - value);i++) {
                                var remove = tablenode.childNodes[tablenode.childNodes.length-1];
                                remove.parentNode.removeChild(remove);
                            }
                            return true;
                        }
                        // add rows..
                        // how many cols on the last row?? = we are going to cheat for the time being.
                        
                        // make a row.
                        var cols = tablenode.getAttribute('cols');
                        if (!cols) { 
                            cols = 1; 
                        }
                        var tr = this._doc.createElement('tr');
                        for (var i = 0;i < cols; i++) {
                            var td = this._doc.createElement('td');
                            td.appendChild(this._doc.createElement('br'));
                            tr.appendChild(td);
                        }
                        for (var i = 0; i < (value - rows); i++) {
                            var newrow = tr.cloneNode(true);
                            tablenode.appendChild(newrow);
                        }
                        return true;
                    }
                    if (key == 'cols') {
                        var confirm_delete = false;
                        
                        for (var i=0;i < tablenode.childNodes.length;i++) {
                            if (tablenode.childNodes[i].tagName.toLowerCase() != 'tr') {
                                continue;
                            }
                            // see how many 
                            
                            var cols = 0;
                            for (var j=0;j < tablenode.childNodes[i].childNodes.length;j++) {
                                if (tablenode.childNodes[i].childNodes[j].tagName.toLowerCase() == 'td') {
                                    if (tablenode.childNodes[i].childNodes[j].hasAttribute('colspan')) {
                                        var add =  1 * tablenode.childNodes[i].childNodes[j].getAttribute('colspan');
                                        if (add > 0) { 
                                            cols = cols + add;
                                        } else {
                                            cols++;
                                        }
                                    } else {
                                        cols++;
                                    }
                                }
                            }
                            if (value == cols) {
                                continue; // nothing changed..?
                            }
                            if (value < cols) { 
                                if (!confirm_delete)  {
                                    confirm_delete = confirm('are you sure you want to remove the last ' + (cols - value) + ' cols?');
                                    if (!confirm_delete) {
                                        return false; // eak bail out after trashing stuff?
                                    }
                                }
                                
                                for (var j=0;j <  (cols - value);j++) {
                                    // no account taken for colspan stuff...
                                    var remove = tablenode.childNodes[i].childNodes[tablenode.childNodes.length-1];
                                    remove.parentNode.removeChild(remove);
                                }
                                return true;
                            }
                            // add cols..
                            // how many cols on the last row?? = we are going to cheat for the time being.
                            var td = this._doc.createElement('td');
                            td.appendChild(this._doc.createElement('br'));
                            
                            
                            for (var j = 0; j < (value - cols); j++) {
                                var newtd = td.cloneNode(true);
                                tablenode.childNodes[i].appendChild(newtd);
                            }
                        }
                        return true;
                    }
                    if (key == 'colspan') { // td colspan...
                        var tdnode = tablenode;
                        tablenode = tdnode.parentNode.parentNode;
                        var trnode = tdnode.parentNode;
                        var cols = tablenode.getAttribute('cols');
                        var leftof = 0;
                        var ourPosition = 0;
                        for (var i=0;i<trnode.childNodes.length;i++) {
                            if (trnode.childNodes[i] == tdnode) {
                                ourPosition = i;
                                break;
                            }
                            if (trnode.childNodes[i].hasAttribute('colspan')) {
                                var add =  1 * trnode.childNodes[i].getAttribute('colspan');
                                if (add > 0) { 
                                    leftof = leftof + add;
                                } else {
                                    leftof++;
                                }
                            } else {
                                leftof++;
                            }
                        }
                        // is new amount too many?
                        if ((leftof + value) > cols) {
                            alert('not enough columns table for that value');
                            return false;
                        }
                        // are we adjusting stuff!!!
                        var addNodes = 0;
                        var removeNodes = value - 1;
                        if (tdnode.hasAttribute('colspan') && (tdnode.getAttribute('colspan') == value)) {
                            // same value - skip;
                            return true;
                        }
                        if (tdnode.hasAttribute('colspan') && (tdnode.getAttribute('colspan') > value)) {
                            // we are reducing.
                            addNodes = tdnode.getAttribute('colspan') -  value ;
                            removeNodes = 0;
                        }
                        if (tdnode.hasAttribute('colspan') && (tdnode.getAttribute('colspan') < value) ) {
                            // we are reducing.
                            removeNodes =  value  - tdnode.getAttribute('colspan') ;
                            addNodes = 0;
                        }
                        //alert('add: ' + addNodes +',remove: ' + removeNodes);
                        if (removeNodes) {
                            for (var i=0;i<removeNodes;i++) {
                                trnode.removeChild(trnode.childNodes[ourPosition+1]);
                            }
                        } else if (addNodes)  {
                            var td = this._doc.createElement('td');
                            td.appendChild(this._doc.createElement('br'));
                           
                            for (var i=0;i<addNodes;i++) {
                                var newtd = td.cloneNode(true);
                                trnode.insertBefore(newtd,trnode.childNodes[ourPosition+1]);
                            }
                        }
                        
                        return true;
                    
                    
                    
                    }
               
                  ]]>
                </body>
            </method>
              
        </implementation>

        <!-- ::::::::::::::::: HANDLERS ::::::::::::::::::::::::: -->

        <handlers>
           <!--  <handler preventdefault="true" event="keypress" key="b" modifiers="control" action="this.exec('bold',null);" /> -->
        </handlers>

    </binding>

</bindings>


<!--            
             <method name="debugGetSelectedHTML">
                  <body><![CDATA[
                    var sel = this.editor.contentWindow.getSelection();
                    if (this.debug) {
                        // alert(sel.rangeCount);
                    }
                    var range = this._createRange(sel);
                    
                    var cloned = range.cloneContents();
                    alert(cloned.childNodes[0].parentNode.tagName);
                    //alert(range.commonAncestorContainer.tagName);
                    
                    /* TESTING FOR INSERTED STUFF...
                    alert(cloned.nodeType);
                 
                    alert(cloned.childNodes[0].nodeType + ':' + cloned.childNodes[0].data.length);
                      alert(cloned.childNodes[1].nodeType);
                    //alert(range.cloneContents().childNodes.length);
                    */
                    var existing = this.getHTML(range.cloneContents(), false, this);
                    alert(existing);
                
                  ]]>
             </body>
            </method> 
             
-->         
