Ignore:
Timestamp:
05/18/05 21:15:06 (14 years ago)
Author:
yermol
Message:

htmlarea.js

. added workaround fix for NASTY FIREFOX BUG resulting in the infamous

uneditable area problem (exception on designMode="on" issue -
refer to bug:


https://bugzilla.mozilla.org/show_bug.cgi?id=207842


and this thread:


http://xinha.gogo.co.nz/punbb/viewtopic.php?id=229


. trailing <BR>'s are no longer stripped out of the document. This

was wreaking havoc on EnterParagraphs?. It's not clear whether or not
this is going to have unanticipated side-effects.

plugins/EnterParagraphs/enter-paragraphs.js

NOT FULLY FUNCTIONAL YET - DOESN'T HANDLE ALL CASES CORRECTLY,
but it's much better than it was I think.

. largely reworked.
. changed obfuscated variables names to make it more readable.
. expanded out nested (x ? y : z) constructs to make it more readable.
. added alot of comments.
. fixed a serious bug in findEachNodeUnder() that was not correctly

handling beginning and end node conditions.

. fixed design flaw that selected a non-existent insertion point for

placing the cursor.

. fixed several exceptions.
. now correctly handles lists by passing the back back to the Gecko

engine if we are in a list with the exception of being at the
first position in the first element in which case we insert
a paragraph before the list and move the cursor back to the first
item on the list.

Location:
branches/unified_backend
Files:
17 edited

Legend:

Unmodified
Added
Removed
  • branches/unified_backend/RELEASE_NOTES.txt

    r121 r172  
    33by: Yermo Lamers of DTLink, LLC 
    44http://www.formvista.com/contact.html 
     5 
     6--------------------------------------------------------------------- 
     72005-05-17: dev snapshot change summary 
     8 
     9examples/simple_sample.php 
     10 
     11. removed styllist. There is some exception problem I haven't tracked 
     12  down yet. 
     13 
     14ddt/ddt.js 
     15 
     16. Should now work under MSIE. 
     17 
     18htmlarea.js 
     19 
     20. added workaround fix for NASTY FIREFOX BUG resulting in the infamous 
     21  uneditable area problem (exception on designMode="on" issue -  
     22  refer to bug:  
     23 
     24  https://bugzilla.mozilla.org/show_bug.cgi?id=207842 
     25 
     26  and this thread: 
     27 
     28  http://xinha.gogo.co.nz/punbb/viewtopic.php?id=229 
     29 
     30. trailing <BR>'s are no longer stripped out of the document. This 
     31  was wreaking havoc on EnterParagraphs. It's not clear whether or not 
     32  this is going to have unanticipated side-effects. 
     33 
     34plugins/EnterParagraphs/enter-paragraphs.js 
     35 
     36  NOT FULLY FUNCTIONAL YET - DOESN'T HANDLE ALL CASES CORRECTLY, 
     37  but it's much better than it was I think. 
     38 
     39. largely reworked. 
     40. changed obfuscated variables names to make it more readable. 
     41. expanded out nested (x ? y : z) constructs to make it more readable. 
     42. added alot of comments. 
     43. fixed a serious bug in findEachNodeUnder() that was not correctly 
     44  handling beginning and end node conditions. 
     45. fixed design flaw that selected a non-existent insertion point for  
     46  placing the cursor. 
     47. fixed several exceptions. 
     48. now correctly handles lists by passing the back back to the Gecko 
     49  engine if we are in a list with the exception of being at the 
     50  first position in the first element in which case we insert 
     51  a paragraph before the list and move the cursor back to the first 
     52  item on the list. 
     53 
     54--------------------------------------------------------------------- 
     552005-05-09: dev snapshot change summary 
     56 
     57plugins/linker/scan.php 
     58 
     59. fixed misformed debug message. 
    560 
    661--------------------------------------------------------------------- 
  • branches/unified_backend/ddt/ddt.js

    r121 r172  
    5252//      Error: uncaught exception: Permission denied to get property Window.DDT_STATUS 
    5353// .    setting the title of the debug window so you can tell which domain it refers to. 
     54// 
     55// 2005-05-12 YmL: 
     56//      .       added _ddtDumpNode() to dump node details along with message. 
     57// 
    5458// ----------------------------- 
     59 
     60 
     61 
     62/** 
     63* browser identification 
     64*/ 
     65 
     66DDT.agt = navigator.userAgent.toLowerCase(); 
     67DDT.is_ie          = ((DDT.agt.indexOf("msie") != -1) && (DDT.agt.indexOf("opera") == -1)); 
     68DDT.is_opera  = (DDT.agt.indexOf("opera") != -1); 
     69DDT.is_mac         = (DDT.agt.indexOf("mac") != -1); 
     70DDT.is_mac_ie = (DDT.is_ie && DDT.is_mac); 
     71DDT.is_win_ie = (DDT.is_ie && !DDT.is_mac); 
     72DDT.is_gecko  = (navigator.product == "Gecko"); 
    5573 
    5674/** 
     
    121139        // 
    122140        // We'll just use the hostname here to make the window name unique. 
    123  
    124         this.popup = window.open( "", "ddt_popup_" + location.host, 
     141        // 
     142        // Something to note, MSIE 6 (at least under win98) throws an exception 
     143        // if there are any "."'s in the window name, so we replace them with underscores here. 
     144 
     145        var window_name = "ddt_popup_" + location.hostname.replace( /[.]/g, "_" ); 
     146 
     147        if (DDT.is_gecko)  
     148                { 
     149                this.popup = window.open( "", "ddt_popup_" + location.host, 
    125150                              "toolbar=no,menubar=no,personalbar=no,width=800,height=450," + 
    126151                              "scrollbars=no,resizable=yes,modal=yes,dependable=yes"); 
     152                } 
     153        else 
     154                { 
     155 
     156                this.popup = window.open("", window_name, 
     157              "toolbar=no,location=no,directories=no,status=no,menubar=no," + 
     158              "scrollbars=no,resizable=yes,width=800,height=450"); 
     159 
     160                } 
     161 
     162        // did we manage to open a window? 
     163 
     164        if (( typeof this.popup == 'undefined' ) || ( this.popup == null )) 
     165                { 
     166                alert( "FAILED TO OPEN DEBUGGING TRACE WINDOW" ); 
     167 
     168                return false; 
     169                } 
    127170 
    128171        // it's possible that the window was left open or we are another object 
    129172        // sharing the same window. 
    130173 
    131         if ( typeof this.popup.DDT_STATUS == 'undefined' ) 
     174        if (( this.popup != null ) && ( typeof this.popup.DDT_STATUS == 'undefined' )) 
    132175                { 
    133176 
     
    207250        } 
    208251 
    209 } 
     252}       // end of _ddt() 
     253 
     254// -------------------------------- 
     255 
     256/** 
     257* dumps key properties from a node. 
     258*/ 
     259 
     260DDT.prototype._ddtDumpNode = function( file, line, msg, node ) 
     261{ 
     262 
     263if ( typeof node == 'undefined' ) 
     264        { 
     265        this._ddt( 
     266                file, line, msg + " -- Node is undefined!" ); 
     267 
     268        return; 
     269        } 
     270 
     271if ( node == null ) 
     272        { 
     273        this._ddt( 
     274                file, line, msg + " -- Node is null!" ); 
     275        } 
     276 
     277this._ddt(  
     278        file, line, msg + "<br>" + this.FragmentToString( node, 0 ) ); 
     279 
     280} // end of _ddtDumpNode() 
    210281 
    211282// -------------------------------- 
     
    255326 
    256327/** 
    257 * dumps an object tree 
    258 * 
    259 * displays a tree of html elements. Design based on method from htmlarea.js 
     328* generates a string description of a document fragment. 
     329* 
     330* returns a tree of html elements. Design based on method from htmlarea.js 
    260331* 
    261332* @see ddtpreproc.php 
    262 * @param root top of tree to display 
     333* @param root top of tree to generate 
    263334* @param level depth level. 
    264335*/ 
    265336 
    266 DDT.prototype._ddtDumpTree = function(root, level)  
     337DDT.prototype.FragmentToString = function(root, level)  
    267338{                                                          
    268 var tag = root.tagName.toLowerCase(), i; 
    269 var ns = HTMLArea.is_ie ? root.scopeName : root.prefix; 
    270  
    271 // FIXME: separated on multiple lines to avoid being picked 
    272 // up by ddtpreproc.php 
    273  
    274 this._ddt(  
    275         ":","0", level + "- " + tag + " [" + ns + "]"  
    276         ); 
    277  
    278 for (i = root.firstChild; i; i = i.nextSibling) 
    279         if (i.nodeType == 1) 
    280                 this._ddtDumpTree(i, level + 2); 
     339 
     340var retval = ""; 
     341 
     342if ( typeof root == 'undefined' ) 
     343        return " root undefined "; 
     344 
     345if ( root == null ) 
     346        return " root is null "; 
     347 
     348// it may be a mozilla range object: 
     349 
     350if ( typeof root.cloneRange != 'undefined' ) 
     351        { 
     352        // we have a range object.  
     353 
     354        retval = "RANGE OBJECT - start offset '" + root.startOffset + "' end offset '" + root.endOffset + "'<br>"; 
     355        retval += "RANGE START:<br>" + this.FragmentToString( root.startContainer, level ); 
     356        retval += "RANGE END:<br>" + this.FragmentToString( root.endContainer, level ); 
     357 
     358        return retval; 
     359        } 
     360 
     361if ( typeof root.childNodes == 'undefined' ) 
     362        return " root is not a node"; 
     363 
     364var childretval = ""; 
     365 
     366// interestingly if you do not declare a local var for the iterator 
     367// it seems to become a static variable which mucks up the recursion 
     368 
     369var i = 0; 
     370 
     371for (i = 0; i < root.childNodes.length; i++) 
     372        { 
     373        childretval += this.FragmentToString( root.childNodes[i], level + 2); 
     374        } 
     375 
     376retval = this.indent( level ) + this._ddtGetNodeType( root ) + " - " + root.childNodes.length + " children <br>" + childretval; 
     377 
     378return retval; 
     379 
    281380}; 
    282381 
     382// ------------------------------------------------- 
     383 
     384/** 
     385* indent by level 
     386*/ 
     387 
     388DDT.prototype.indent = function( level ) 
     389{ 
     390 
     391var retval = ""; 
     392 
     393for (i = 0; i<level; i++ ) 
     394        { 
     395        retval += "&nbsp;&nbsp;"; 
     396        } 
     397 
     398return retval; 
     399 
     400} 
     401// ----------------------------------------- 
     402 
     403/** 
     404* displays node type 
     405*/ 
     406 
     407DDT.prototype._ddtGetNodeType = function( node ) 
     408{ 
     409 
     410var retval = ""; 
     411 
     412if ( typeof node == 'undefined' ) 
     413        { 
     414        return "TYPE_IS_UNDEFINED"; 
     415        } 
     416 
     417if ( node == null ) 
     418        { 
     419        return "TYPE_IS_NULL!"; 
     420        } 
     421 
     422if ( typeof node.nodeType == 'undefined' ) 
     423        { 
     424        return "NOT_A_NODE_OBJECT - type is '" + typeof node + "'"; 
     425        } 
     426 
     427switch ( node.nodeType ) 
     428        { 
     429 
     430        case 1: 
     431                retval = "ELEMENT_NODE - tag '" + node.nodeName + "'"; 
     432                return retval; 
     433                break; 
     434 
     435        case 2: 
     436                return "ATTRIBUTE_NODE"; 
     437                break; 
     438 
     439        case 3: 
     440                retval = "TEXT_NODE"; 
     441                retval = retval + " contents '" + node.nodeValue + "'"; 
     442                return retval; 
     443 
     444                break; 
     445 
     446        case 4: 
     447                return "CDATA_SECTION_NODE"; 
     448                break; 
     449 
     450        case 5: 
     451                return "ENTITY_REFERENCE_NODE"; 
     452                break; 
     453 
     454        case 6: 
     455                return "ENTITY_NODE"; 
     456                break; 
     457 
     458        case 7: 
     459                return "PROCESSING_INSTRUCTION_NODE"; 
     460                break; 
     461 
     462        case 8: 
     463                return "COMMENT_NODE"; 
     464                break; 
     465 
     466        case 9: 
     467                return "DOCUMENT_NODE"; 
     468                break; 
     469 
     470        case 10: 
     471                return "DOCUMENT_TYPE_NODE"; 
     472                break; 
     473 
     474        case 11: 
     475                retval = "DOCUMENT_FRAGMENT_NODE"; 
     476 
     477                return retval; 
     478                break; 
     479 
     480        case 12: 
     481                return "NOTATION_NODE"; 
     482                break; 
     483 
     484        default: 
     485                return "UNKNOWN_NODE!"; 
     486                break; 
     487 
     488        } // end of switch 
     489 
     490};      // end of _ddtDumpNode() 
     491 
     492// ---------------------------------------------------------- 
     493 
     494/** 
     495* getHTMLSource() - returns HTML source for display in a browser window. 
     496*/ 
     497 
     498DDT.prototype.getHTMLSource = function( html ) 
     499{ 
     500 
     501html = html.replace( /</ig, "&lt;" ); 
     502html = html.replace( />/ig, "&gt;" ); 
     503html = html.replace( /&/ig, "&amp;" ); 
     504html = html.replace(/\xA0/g, "&nbsp;"); 
     505html = html.replace(/\x22/g, "&quot;"); 
     506 
     507return html; 
     508 
     509}       // end of showHTML() 
     510 
    283511// END 
    284512 
  • branches/unified_backend/ddt/ddt.php

    r121 r172  
    8989                } 
    9090 
    91         fputs( $fvDEBUG[ "logfile_fp" ], "$msgline" ); 
     91        fwrite( $fvDEBUG[ "logfile_fp" ], $msgline ); 
    9292        fflush( $fvDEBUG[ "logfile_fp" ] ); 
    9393 
  • branches/unified_backend/examples/full_example-body.php

    r121 r172  
    180180    } 
    181181 
    182     window.onload = xinha_init; 
     182    // calling xinha_init twice can cause a nasty little exception. 
     183    // window.onload = xinha_init; 
     184 
    183185  </script> 
    184186</head> 
     
    204206    ---------------------------------------------------------------------------> 
    205207 
    206         <div id="lipsum" style="display:none"> 
     208    <div id="lipsum" style="display:none"><h1>TEST</h1></div> 
     209 
     210        <div id="lipsumx" style="display:none"> 
    207211          <p>This is an example of a Xinha editor with extensive trace messages 
    208212                         turned on. To turn off trace messages, assuming you have the source, just 
     
    228232                         file from the Xinha_ub branch.</p> 
    229233        </div> 
     234 
    230235        <script src="full_example.js"></script> 
    231236 
  • branches/unified_backend/examples/full_example-menu.html

    r121 r172  
    3737      <legend>Plugins</legend> 
    3838      <label> 
     39        <input type="checkbox" name="plugins" value="EnterParagraphs"  /> EnterParagraphs 
     40      </label> 
     41      <label> 
    3942        <input type="checkbox" name="plugins" value="CSS"  /> CSS 
    4043      </label> 
     
    4649      </label> 
    4750      <label> 
    48         <input type="checkbox" name="plugins" value="FullScreen" checked /> FullScreen 
     51        <input type="checkbox" name="plugins" value="FullScreen" /> FullScreen 
    4952      </label> 
    5053      <label> 
    51         <input type="checkbox" name="plugins" value="CharacterMap" checked /> CharacterMap 
     54        <input type="checkbox" name="plugins" value="CharacterMap" /> CharacterMap 
    5255      </label> 
    5356      <label> 
     
    5558      </label> 
    5659      <label> 
    57         <input type="checkbox" name="plugins" value="ListType" checked /> ListType 
     60        <input type="checkbox" name="plugins" value="ListType" /> ListType 
    5861      </label> 
    5962 
    6063      <label> 
    61         <input type="checkbox" name="plugins" value="Stylist" checked /> Stylist 
     64        <input type="checkbox" name="plugins" value="Stylist" /> Stylist 
    6265      </label> 
    6366 
    6467      <label> 
    65         <input type="checkbox" name="plugins" value="TableOperations" checked /> TableOperations 
     68        <input type="checkbox" name="plugins" value="TableOperations" /> TableOperations 
    6669      </label> 
    6770 
    6871      <label> 
    69         <input type="checkbox" name="plugins" value="InsertAnchor" checked /> InsertAnchor 
     72        <input type="checkbox" name="plugins" value="InsertAnchor" /> InsertAnchor 
    7073      </label> 
    7174    </fieldset> 
  • branches/unified_backend/examples/simple_example.php

    r121 r172  
    3030    //  eg: _editor_url = "../"; 
    3131    // in this example we do a little regular expression to find the absolute path. 
    32     _editor_url  = document.location.href.replace(/examples\/simple_example\.html.*/, '') 
     32    _editor_url  = document.location.href.replace(/examples\/simple_example\.php.*/, '') 
    3333    _editor_lang = "en";      // And the language we need to use in the editor. 
    3434  </script> 
     
    190190 
    191191    <textarea id="TextArea1" name="TextArea1" rows="10" cols="80" style="width:100%"> 
    192          This is the content of TextArea1 from xinha_ub/examples/simple_example.html.<br> 
     192         This is the content of TextArea1 from xinha_ub/examples/simple_example.php.<br> 
    193193         In order to see the new debugging trace messages you will need to turn off 
    194194         popup blockers for this site.<br> 
     
    196196         commenting out or uncomments the _ddtOn() line. The same applies to the trace 
    197197         messages inside the HTMLArea object in htmlarea.js. 
     198         The version of EnterParagraphs in this editor should be largely fixed. If you notice 
     199         any problems please report them in the forums. 
    198200         </textarea> 
    199201 
  • branches/unified_backend/htmlarea.js

    r121 r172  
    273273  * 
    274274  * set to 'built-in', 'dirty' or 'best' 
    275   * built-in: will (may) use 'br' instead of 'p' tags 
     275  * built-in: will (may) use 'br' instead of 'p' tags (passes it off to the brower builtin handler) 
    276276  * dirty   : will use p and work good enough for the majority of cases, 
    277277  * best    : works the best, but it's about 12kb worth of javascript 
     
    280280  */ 
    281281 
    282   this.mozParaHandler = 'best';  
     282  this.mozParaHandler = 'built-in';  
    283283 
    284284  /** 
     
    21392139/** 
    21402140* getHTMLWrapper() 
     2141* 
     2142* Called, for instance, when switching from wysiwyg to text mode.  
    21412143*/ 
    21422144 
     
    21902192      var i; 
    21912193      var root_tag = (root.nodeType == 1) ? root.tagName.toLowerCase() : ''; 
     2194 
     2195                        // removes br tags from the end of root level.  
     2196 
     2197/* yml: Temporarily disabling. 
     2198 
    21922199      if (root_tag == 'br' && !root.nextSibling) 
     2200                                { 
     2201                          HTMLArea._ddt( "htmlarea.js","2146", "getHTMLWrapper(): skipping (removing) terminating root level BR tag." ); 
    21932202        break; 
     2203                                } 
     2204*/ 
    21942205 
    21952206      if (outputRoot) 
     2207                                { 
    21962208        outputRoot = !(editor.config.htmlRemoveTags && editor.config.htmlRemoveTags.test(root_tag)); 
     2209                                } 
    21972210 
    21982211      if (HTMLArea.is_ie && root_tag == "head")  
    2199                   { 
     2212                          { 
    22002213        if (outputRoot) 
     2214                                        { 
    22012215          html += "<head>"; 
     2216                                        } 
     2217 
    22022218        // lowercasize 
     2219 
    22032220        var save_multiline = RegExp.multiline; 
    22042221        RegExp.multiline = true; 
    2205         var txt = root.innerHTML.replace(HTMLArea.RE_tagName, function(str, p1, p2)  
    2206                     { 
    2207           return p1 + p2.toLowerCase(); 
    2208           }); 
     2222        var txt = root.innerHTML.replace(HTMLArea.RE_tagName,  
     2223                                                                                function(str, p1, p2)  
     2224                                                                            { 
     2225                                                          return p1 + p2.toLowerCase(); 
     2226                                                          }); 
    22092227 
    22102228        RegExp.multiline = save_multiline; 
    22112229        html += txt; 
     2230 
    22122231        if (outputRoot) 
     2232                                        { 
    22132233          html += "</head>"; 
     2234                                        } 
     2235 
    22142236        break; 
    22152237        }  
     
    22202242        var attrs = root.attributes; 
    22212243        for (i = 0; i < attrs.length; ++i)  
    2222                     { 
     2244                            { 
    22232245          var a = attrs.item(i); 
    22242246          if (!a.specified)  
    2225                            { 
     2247                                                { 
    22262248            continue; 
    22272249            } 
     
    22292251          var name = a.nodeName.toLowerCase(); 
    22302252          if (/_moz_editor_bogus_node/.test(name))  
    2231                            { 
     2253                                                { 
    22322254            html = ""; 
    22332255            break; 
     
    22432265 
    22442266          if (name != "style")  
    2245                            { 
     2267                                                { 
    22462268 
    22472269            // IE5.5 reports 25 when cellSpacing is 
     
    22572279 
    22582280            if (typeof root[a.nodeName] != "undefined" && name != "href" && name != "src" && !/^on/.test(name))  
    2259                                   { 
     2281                                                        { 
    22602282              value = root[a.nodeName]; 
    22612283              }  
    2262                                 else  
    2263                                   { 
     2284                                                else  
     2285                                                        { 
    22642286              value = a.nodeValue; 
    22652287 
     
    22692291 
    22702292              if (HTMLArea.is_ie && (name == "href" || name == "src"))  
    2271                                     { 
     2293                                                    { 
     2294 
     2295                                                                HTMLArea._ddt( "htmlarea.js", "2292", "getHTMLWrapper(): because we are ie and have an href or src attribute we are calling stripBaseUrl" ); 
     2296 
    22722297                value = editor.stripBaseURL(value); 
    22732298                } 
    22742299              } 
    22752300            }  
    2276                         else  
    2277                            {  
     2301                                else  
     2302                                                {  
    22782303                                 
    2279                                 // IE fails to put style in attributes list 
     2304                                                // IE fails to put style in attributes list 
    22802305            // FIXME: cssText reported by IE is UPPERCASE 
    22812306 
     
    22842309 
    22852310          if (/^(_moz)?$/.test(value))  
    2286                            { 
     2311                                                { 
    22872312            // Mozilla reports some special tags 
    22882313            // here; we don't need them. 
     
    22952320 
    22962321        if (html != "")  
    2297                     { 
     2322                                        { 
    22982323          html += closed ? " />" : ">"; 
    22992324          } 
     
    23022327 
    23032328      for (i = root.firstChild; i; i = i.nextSibling)  
    2304                   { 
     2329                                { 
    23052330        html += HTMLArea.getHTMLWrapper(i, true, editor); 
    23062331        } 
    23072332 
    23082333      if (outputRoot && !closed)  
    2309                   { 
     2334                                { 
    23102335        html += "</" + root.tagName.toLowerCase() + ">"; 
    23112336        } 
     
    30843109 
    30853110      obj.swapImage = function(newimg) 
    3086         { 
    3087         if(typeof newimg != 'string') 
    3088           { 
    3089           img.src = newimg[0]; 
    3090           img.style.position = 'relative'; 
    3091           img.style.top  = newimg[2] ? ('-' + (18 * (newimg[2] + 1)) + 'px') : '-18px'; 
    3092           img.style.left = newimg[1] ? ('-' + (18 * (newimg[1] + 1)) + 'px') : '-18px'; 
    3093           } 
    3094         else 
    3095           { 
    3096           obj.imgel.src = newimg; 
    3097           img.style.top = '0px'; 
    3098           img.style.left = '0px'; 
    3099           } 
    3100         } 
     3111                                                                        { 
     3112                                                                        if(typeof newimg != 'string') 
     3113                                                                          { 
     3114                                                                          img.src = newimg[0]; 
     3115                                                                          img.style.position = 'relative'; 
     3116                                                                          img.style.top  = newimg[2] ? ('-' + (18 * (newimg[2] + 1)) + 'px') : '-18px'; 
     3117                                                                          img.style.left = newimg[1] ? ('-' + (18 * (newimg[1] + 1)) + 'px') : '-18px'; 
     3118                                                                          } 
     3119                                                                        else 
     3120                                                                          { 
     3121                                                                          obj.imgel.src = newimg; 
     3122                                                                          img.style.top = '0px'; 
     3123                                                                          img.style.left = '0px'; 
     3124                                                                          } 
     3125                                                                        }       // end of function definition. 
    31013126 
    31023127      }  
     
    32093234*/ 
    32103235 
    3211 HTMLArea.prototype.generate = function () 
     3236HTMLArea.prototype.generate = function() 
    32123237  { 
    32133238 
    32143239  this.ddt._ddt( "htmlarea.js","3214", "generate(): top" ); 
    32153240 
    3216   var editor = this;    // we'll need "this" in some nested functions 
     3241        // we need "this" in some nested functions (i.e. closures) so a local 
     3242        // variable is used to "transmit" it to the enclosed function. Weird 
     3243        // javascript enclosure concept. 
     3244 
     3245  var editor = this;     
    32173246 
    32183247  // If this is gecko, set up the paragraph handling now 
     
    32273256          { 
    32283257 
    3229                          this.ddt._ddt( "htmlarea.js","3229", "generate(): mozParaHandler config set to 'best'. Loading EnterParagraphs" ); 
     3258                                        this.ddt._ddt( "htmlarea.js","3229", "generate(): mozParaHandler config set to 'best'. Loading EnterParagraphs" ); 
    32303259 
    32313260          EnterParagraphs = 'null'; 
    3232           HTMLArea._loadback 
    3233             (_editor_url + 'plugins/EnterParagraphs/enter-paragraphs.js', function() { editor.registerPlugin('EnterParagraphs'); editor.generate(); } ); 
     3261          HTMLArea._loadback(_editor_url + 'plugins/EnterParagraphs/enter-paragraphs.js',  
     3262                                                                                        function()  
     3263                                                                                                {  
     3264                                                                                                editor.generate();  
     3265                                                                                                return true; 
     3266                                                                                                } ); 
     3267 
    32343268          return false; 
     3269 
    32353270          } 
     3271 
     3272                                editor.registerPlugin(eval('EnterParagraphs')); 
     3273 
    32363274        } 
    32373275 
     
    33423380        { 
    33433381 
    3344                   this.ddt._ddt( "htmlarea.js","3344", "generate(): f.onsubmit(): top" ); 
     3382                                this.ddt._ddt( "htmlarea.js","3344", "generate(): f.onsubmit(): top" ); 
    33453383 
    33463384        var a = this.__msh_prevOnSubmit; 
     
    34593497  this.notifyOn('panel_change',function(){editor.setInnerSize();}); 
    34603498 
    3461   this.ddt._ddt( "htmlarea.js","3461", "generate(): bottom before timeout call to initIframe()" ); 
    3462  
    3463   // IMPORTANT: we have to allow Mozilla a short time to recognize the 
    3464   // new frame.  Otherwise we get a stupid exception. 
    3465  
    3466   setTimeout(function() { editor.initIframe()}, 50); 
     3499  this.ddt._ddt( "htmlarea.js","3461", "generate(): bottom before event call to initIframe()" ); 
     3500 
     3501        // instead of using a timeout which by definition produces an occassional race condition 
     3502        // depending on performance, we tie calling initFrame to the frame being completely 
     3503        // loaded. 
     3504        // 
     3505        // See: 
     3506        // 
     3507        // https://bugzilla.mozilla.org/show_bug.cgi?id=207842 
     3508        // 
     3509        // notably the link to: 
     3510        // 
     3511        // http://derekdev.com/mozilla/iframeworky.html 
     3512        // 
     3513        // So far I can't seem to get this EventListener to "turn off" but this does  
     3514        // seem to fix the exceptions problem we've been seeing and it's alot 
     3515        // cleaner than "waiting". Under some circumstances I'm noticing quite a long 
     3516        // delay here depending on how long FireFox has been running. 
     3517 
     3518        if ( HTMLArea.is_gecko ) 
     3519                { 
     3520 
     3521                // need to get a var into the closure below. 
     3522 
     3523                editor.isGenerated = false; 
     3524 
     3525                this._iframe.addEventListener("load",  
     3526                                                function(e) 
     3527                                { 
     3528 
     3529                                                        if ( !editor.isGenerated ) 
     3530                                                                { 
     3531                                                                editor.isGenerated = true; 
     3532                        editor.initIframe(); 
     3533                                                                } 
     3534 
     3535                                                        return true; 
     3536 
     3537                                },  
     3538                                                false); 
     3539                } 
     3540        else 
     3541                { 
     3542 
     3543                // MSIE uses a different method to attach events. MSIE does not 
     3544                // suffer from the bug which forces us to wait for the iFrame in  
     3545                // firefox but it seems like a good idea to do it the same way 
     3546                // instead of calling initframe directly. Both seem to work equally 
     3547                // as well ...  
     3548 
     3549    this._iframe.attachEvent("onload",                                           
     3550                                                function(e) 
     3551                                { 
     3552 
     3553                                                        if ( !editor.isGenerated ) 
     3554                                                                { 
     3555                                                                editor.isGenerated = true; 
     3556                        editor.initIframe(); 
     3557                                                                } 
     3558 
     3559                                                        return true; 
     3560 
     3561                                }); 
     3562                } 
     3563 
     3564        return true; 
    34673565 
    34683566  };  // end of HTMLArea.prototype.generate() 
     
    34883586 
    34893587    if (!doc)  
    3490            { 
     3588                        { 
    34913589      // Try again.. 
    34923590      // FIXME: don't know what else to do here.  Normally 
     
    34943592 
    34953593      if (HTMLArea.is_gecko)  
    3496                   { 
     3594                          { 
    34973595        setTimeout(function() { editor.initIframe()}, 50); 
    34983596        return false; 
    34993597        }  
    3500                 else  
    3501                   { 
     3598                        else  
     3599                          { 
    35023600        alert("ERROR: IFRAME can't be initialized."); 
    35033601        } 
     
    35063604  catch(e) 
    35073605    { 
     3606 
     3607    alert("EXCEPTION: couldn't get doc in initFrame - delaying and returning."); 
     3608 
    35083609    setTimeout(function() { editor.initIframe()}, 50); 
     3610 
     3611                return false; 
    35093612    } 
    35103613 
     
    35163619    html += "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=" + editor.config.charSet + "\">\n"; 
    35173620 
    3518     if(typeof editor.config.baseHref != 'undefined' && editor.config.baseHref != null) 
     3621    if ( typeof editor.config.baseHref != 'undefined' && editor.config.baseHref != null) 
    35193622      { 
    35203623      html += "<base href=\"" + editor.config.baseHref + "\"/>\n"; 
     
    35523655    { 
    35533656    var html = editor.inwardHtml(editor._textArea.value); 
     3657 
    35543658    if (html.match(HTMLArea.RE_doctype))  
    3555            { 
     3659                        { 
    35563660      editor.setDoctype(RegExp.$1); 
    35573661      html = html.replace(HTMLArea.RE_doctype, ""); 
    35583662      } 
     3663 
    35593664    doc.open(); 
    35603665    doc.write(html); 
     
    39074012    { 
    39084013 
    3909     try{HTMLArea.last_on.designMode = 'off';} catch(e) { } 
     4014                // if this is the first time here last_on has not been set so this will 
     4015                // generate an exception. 
     4016 
     4017    try  
     4018                        { 
     4019                        HTMLArea.last_on.designMode = 'off'; 
     4020                        }  
     4021                catch(e)  
     4022                        { 
     4023                  this.ddt._ddt( "htmlarea.js","3904", "activateEditor(): exception trying to set last_on.designMode to off. First time here?" ); 
     4024                        } 
    39104025 
    39114026    this.ddt._ddt( "htmlarea.js","3911", "activateEditor(): _iframe.style.display is '" + this._iframe.style.display + "'" ); 
    39124027 
    3913     if(this._iframe.style.display == 'none') 
     4028    if ( this._iframe.style.display == 'none' ) 
    39144029      { 
    39154030      this._iframe.style.display = ''; 
     
    39194034    else 
    39204035      { 
    3921  
    3922                 this.ddt._ddt( "htmlarea.js","3922", "activateEditor(): setting designMode to on" ); 
    3923  
    3924       this._doc.designMode = 'on'; 
    3925       } 
    3926     } 
    3927   else 
    3928     { 
    3929  
    3930          this.ddt._ddt( "htmlarea.js","3930", "activateEditor(): Setting contentEditable to true" ); 
     4036                        this.ddt._ddt( "htmlarea.js","3922", "activateEditor(): setting designMode to on" ); 
     4037 
     4038                        // under FireFox we're endlessly getting exceptions here. 
     4039 
     4040                        try 
     4041                                { 
     4042        this._doc.designMode = 'on'; 
     4043                                } 
     4044                        catch( e ) 
     4045                                { 
     4046                                alert( "EXCEPTION - failed to turn design mode on in activateEditor() - " + e + "'" ); 
     4047                                } 
     4048      } 
     4049    } 
     4050  else if ( HTMLArea.is_ie ) 
     4051    { 
     4052 
     4053                this.ddt._ddt( "htmlarea.js","3930", "activateEditor(): Setting contentEditable to true" ); 
    39314054 
    39324055    this._doc.body.contentEditable = true; 
    39334056    } 
     4057        else 
     4058                { 
     4059                this.ddt._ddt( "htmlarea.js","3930", "activateEditor(): UNHANDLED CASE." ); 
     4060 
     4061                // alert( "INTERNAL ERROR - activateEditor - unhandled case" ); 
     4062                } 
    39344063 
    39354064  HTMLArea.last_on = this._doc; 
     
    39734102  { 
    39744103 
     4104  if (typeof mode == "undefined")  
     4105    { 
     4106    mode = ((this._editMode == "textmode") ? "wysiwyg" : "textmode"); 
     4107    } 
     4108 
    39754109  this.ddt._ddt( "htmlarea.js","3975", "setMode(): setting mode to '" + mode + "'" ); 
    39764110 
    3977   if (typeof mode == "undefined")  
    3978     { 
    3979     mode = ((this._editMode == "textmode") ? "wysiwyg" : "textmode"); 
    3980     } 
    3981  
    39824111  switch (mode)  
    39834112    { 
    39844113    case "textmode": 
    39854114      { 
     4115 
    39864116      var html = this.outwardHtml(this.getHTML()); 
    39874117      this._textArea.value = html; 
     4118 
     4119                        this.ddt._ddt( "htmlarea.js", "3986", "setMode(): textmode. called getHTML composed into outwardHTML and set the textarea value. html set was '" + this.ddt.getHTMLSource(html) + "'" ); 
    39884120 
    39894121      // Hide the iframe 
     
    40024134    case "wysiwyg": 
    40034135      { 
     4136 
     4137                        this.ddt._ddt( "htmlarea.js", "3986", "setMode(): textmode. calling getHTML composed into inwardHTML and setting the innerHTML or fullpage value." ); 
     4138 
    40044139      var html = this.inwardHtml(this.getHTML()); 
    40054140      this.deactivateEditor(); 
     
    40074142        { 
    40084143        this._doc.body.innerHTML = html; 
     4144 
     4145                                this.ddt._ddtDumpNode( "htmlarea.js", "3986", "setMode(): wysiwyg. after setting innerHTML body contents are:", this._doc.body ); 
     4146 
    40094147        } 
    40104148      else 
     
    40124150        this.setFullHTML(html); 
    40134151        } 
     4152 
    40144153      this._iframe.style.display   = ''; 
    40154154      this._textArea.style.display = "none"; 
     
    40364175  // this.focusEditor(); 
    40374176 
     4177        this.ddt._ddt( "htmlarea.js", "4044", "setMode(): informing any plugins that interested of the mode change" ); 
     4178 
    40384179  for (var i in this.plugins)  
    40394180    { 
    40404181    var plugin = this.plugins[i].instance; 
    4041     if (typeof plugin.onMode == "function") plugin.onMode(mode); 
     4182    if (typeof plugin.onMode == "function")  
     4183                        { 
     4184                        this.ddt._ddt( "htmlarea.js", "4044", "setMode(): calling onMode in plugin '" + plugin.name + "'" ); 
     4185                        plugin.onMode(mode); 
     4186                        } 
    40424187    } 
    40434188  };  // end of setMode() 
     
    40994244  { 
    41004245 
    4101   this.ddt._ddt( "htmlarea.js","4101", "registerPlugin(): top" ); 
    4102  
    41034246  var plugin = arguments[0]; 
     4247 
     4248  this.ddt._ddt( "htmlarea.js","4101", "registerPlugin(): top with plugin '" + plugin + "'" ); 
     4249 
    41044250  var args = []; 
    41054251  for (var i = 1; i < arguments.length; ++i) 
     
    41084254  return this.registerPlugin2(plugin, args); 
    41094255  }; 
     4256 
     4257// ----------------------------------------------------------------- 
    41104258 
    41114259/** 
     
    41244272 
    41254273  if (typeof plugin == "string") 
     4274                { 
     4275          this.ddt._ddt( "htmlarea.js","4123", "registerPlugin2(): plugin '" + plugin + "' is a string." ); 
    41264276    plugin = eval(plugin); 
    4127  
    4128   if (typeof plugin == "undefined")  
    4129     { 
    4130  
    4131          this.ddt._ddt( "htmlarea.js","4131", "registerPlugin2(): INTERNAL ERROR: plugin is undefined. " ); 
     4277                } 
     4278 
     4279  if ((typeof plugin == "undefined") || ( plugin == null )) 
     4280    { 
     4281 
     4282                this.ddt._ddt( "htmlarea.js","4131", "registerPlugin2(): INTERNAL ERROR: plugin is undefined. " ); 
    41324283 
    41334284    /* FIXME: This should never happen. But why does it do? */ 
     
    41354286    } 
    41364287 
    4137   var obj = new plugin(this, args); 
     4288        // FIXME: in the multiple editor on a page case we sometimes get a null plugin 
     4289        // here ... why? 
     4290 
     4291        try 
     4292                { 
     4293          var obj = new plugin(this, args); 
     4294 
     4295                this.ddt._ddt( "htmlarea.js","4131", "registerPlugin2(): after successfully creating the plugin. " ); 
     4296 
     4297                } 
     4298        catch(e) 
     4299                { 
     4300                this.ddt._ddt( "htmlarea.js","4131", "registerPlugin2(): unable to create the plugin. '" + e + "'" ); 
     4301 
     4302                alert( "INTERNAL ERROR - registerPlugin2(): UNABLE TO CONSTRUCT PLUGIN '" + plugin + "' - '" + e + "'" ); 
     4303 
     4304                return false; 
     4305                } 
    41384306 
    41394307  if (obj)  
     
    41514319    }  
    41524320  else 
     4321                { 
    41534322    alert("Can't register plugin " + plugin.toString() + "."); 
     4323                } 
    41544324 
    41554325  };  // end of registerPlugin2 
     
    44194589        // We don't want to focus the field unless at least one field has been activated. 
    44204590 
    4421         if(HTMLArea.last_on) 
     4591        if ( HTMLArea.last_on ) 
    44224592          { 
    44234593          this.activateEditor(); 
     
    45834753    ancestors = this.getAllAncestors(); 
    45844754    if (this.config.statusBar && !noStatus)  
    4585            { 
     4755                        { 
    45864756      this._statusBarTree.innerHTML = HTMLArea._lc("Path") + ": "; // clear 
    45874757      for (var i = ancestors.length; --i >= 0;)  
    4588                   { 
     4758                                { 
    45894759        var el = ancestors[i]; 
    45904760        if (!el)  
    4591                     { 
    4592  
    4593                          this.ddt._ddt( "htmlarea.js","4593", "updateToolbar(): INTERNAL ERROR" ); 
     4761                                        { 
     4762 
     4763                                        this.ddt._ddt( "htmlarea.js","4593", "updateToolbar(): INTERNAL ERROR" ); 
    45944764 
    45954765          // hell knows why we get here; this 
     
    46064776 
    46074777        a.onclick = function()  
    4608                     { 
    4609           this.blur(); 
    4610           this.editor.selectNodeContents(this.el); 
    4611           this.editor.updateToolbar(true); 
    4612           return false; 
    4613           }; 
     4778                                                                            { 
     4779                                                          this.blur(); 
     4780                                                          this.editor.selectNodeContents(this.el); 
     4781                                                          this.editor.updateToolbar(true); 
     4782                                                          return false; 
     4783                                                        }; 
    46144784 
    46154785        a.oncontextmenu = function()  
    4616                     { 
    4617  
    4618           // TODO: add context menu here 
    4619  
    4620           this.blur(); 
    4621           var info = "Inline style:\n\n"; 
    4622           info += this.el.style.cssText.split(/;\s*/).join(";\n"); 
    4623           alert(info); 
    4624           return false; 
    4625           }; 
     4786                                                                                                    { 
     4787 
     4788                                                                                  // TODO: add context menu here 
     4789 
     4790                                                                                  this.blur(); 
     4791                                                                                  var info = "Inline style:\n\n"; 
     4792                                                                                  info += this.el.style.cssText.split(/;\s*/).join(";\n"); 
     4793                                                                                  alert(info); 
     4794                                                                                  return false; 
     4795                                                                                  }; 
    46264796 
    46274797        var txt = el.tagName.toLowerCase(); 
    46284798        a.title = el.style.cssText; 
    46294799        if (el.id)  
    4630                     { 
     4800                            { 
    46314801          txt += "#" + el.id; 
    46324802          } 
    46334803 
    46344804        if (el.className)  
    4635                     { 
     4805                            { 
    46364806          txt += "." + el.className; 
    46374807          } 
     
    46404810        this._statusBarTree.appendChild(a); 
    46414811        if (i != 0)  
    4642                     { 
     4812                            { 
    46434813          this._statusBarTree.appendChild(document.createTextNode(String.fromCharCode(0xbb))); 
    46444814          } 
     
    46554825 
    46564826    if (btn.context && !text)  
    4657            { 
     4827                        { 
    46584828      inContext = false; 
    46594829      var context = btn.context; 
     
    46614831 
    46624832      if (/(.*)\[(.*?)\]/.test(context))  
    4663                   { 
     4833                        { 
    46644834        context = RegExp.$1; 
    46654835        attrs = RegExp.$2.split(","); 
     
    46694839      var match = (context == "*"); 
    46704840      for (var k = 0; k < ancestors.length; ++k)  
    4671                   { 
     4841                        { 
    46724842        if (!ancestors[k])  
    4673                     { 
    4674  
    4675                          this.ddt._ddt( "htmlarea.js","4675", "updateToolbar(): INTERNAL ERROR" ); 
     4843                        { 
     4844 
     4845                                        this.ddt._ddt( "htmlarea.js","4675", "updateToolbar(): INTERNAL ERROR" ); 
    46764846 
    46774847          // the impossible really happens. 
     
    46804850 
    46814851        if (match || (ancestors[k].tagName.toLowerCase() == context))  
    4682                     { 
     4852                            { 
    46834853          inContext = true; 
    46844854          for (var ka = 0; ka < attrs.length; ++ka)  
    4685                            { 
     4855                                                { 
    46864856            if (!eval("ancestors[k]." + attrs[ka]))  
    4687                                   { 
     4857                                                        { 
    46884858              inContext = false; 
    46894859              break; 
     
    46924862 
    46934863          if (inContext)  
    4694                            { 
     4864                                                { 
    46954865            break; 
    46964866            } 
     
    47014871    btn.state("enabled", (!text || btn.text) && inContext); 
    47024872    if (typeof cmd == "function")  
    4703            { 
     4873                        { 
    47044874      continue; 
    47054875      } 
     
    47094879    var dropdown = this.config.customSelects[cmd]; 
    47104880    if ((!text || btn.text) && (typeof dropdown != "undefined"))  
    4711            { 
     4881                        { 
    47124882      dropdown.refresh(this); 
    47134883      continue; 
     
    47204890        { 
    47214891        if (!text) try  
    4722                     { 
     4892                                        { 
    47234893          var value = ("" + doc.queryCommandValue(cmd)).toLowerCase(); 
    47244894 
    47254895          if (!value)  
    4726                            { 
     4896                                                { 
    47274897            btn.element.selectedIndex = 0; 
    47284898            break; 
     
    47474917            } 
    47484918          btn.element.selectedIndex = 0; 
    4749           } catch(e) {}; 
     4919          }  
     4920                                catch(e)  
     4921                                        {}; 
    47504922        } 
    4751         break; 
     4923                                 
     4924                        break; 
    47524925 
    47534926      // It's better to search for the format block by tag name from the 
     
    47844957      case "textindicator": 
    47854958        if (!text)  
    4786                     { 
    4787           try {with (btn.element.style)  
    4788                            { 
    4789             backgroundColor = HTMLArea._makeColor( 
    4790               doc.queryCommandValue(HTMLArea.is_ie ? "backcolor" : "hilitecolor")); 
    4791  
    4792             if (/transparent/i.test(backgroundColor))  
    4793                                   { 
    4794               // Mozilla 
    4795               backgroundColor = HTMLArea._makeColor(doc.queryCommandValue("backcolor")); 
    4796               } 
    4797  
    4798             color = HTMLArea._makeColor(doc.queryCommandValue("forecolor")); 
    4799             fontFamily = doc.queryCommandValue("fontname"); 
    4800             fontWeight = doc.queryCommandState("bold") ? "bold" : "normal"; 
    4801             fontStyle = doc.queryCommandState("italic") ? "italic" : "normal"; 
    4802             }} catch (e)  
    4803                                 { 
     4959                        { 
     4960          try  
     4961                                                { 
     4962                                                with (btn.element.style)  
     4963                                                        { 
     4964                backgroundColor = HTMLArea._makeColor( 
     4965                doc.queryCommandValue(HTMLArea.is_ie ? "backcolor" : "hilitecolor")); 
     4966 
     4967                    if (/transparent/i.test(backgroundColor))  
     4968                                                                { 
     4969                  // Mozilla 
     4970                backgroundColor = HTMLArea._makeColor(doc.queryCommandValue("backcolor")); 
     4971                      } 
     4972 
     4973                  color = HTMLArea._makeColor(doc.queryCommandValue("forecolor")); 
     4974                fontFamily = doc.queryCommandValue("fontname"); 
     4975              fontWeight = doc.queryCommandState("bold") ? "bold" : "normal"; 
     4976                    fontStyle = doc.queryCommandState("italic") ? "italic" : "normal"; 
     4977                  } 
     4978                                                }  
     4979                                        catch (e)  
     4980                                                { 
    48044981            // alert(e + "\n\n" + cmd); 
    48054982            } 
     
    48074984        break; 
    48084985 
    4809       case "htmlmode": btn.state("active", text); break; 
     4986      case "htmlmode":  
     4987                         
     4988                                btn.state("active", text);  
     4989                                break; 
     4990 
    48104991      case "lefttoright": 
    48114992      case "righttoleft": 
     
    48225003        cmd = cmd.replace(/(un)?orderedlist/i, "insert$1orderedlist"); 
    48235004        try  
    4824                     { 
     5005                                        { 
    48255006          btn.state("active", (!text && doc.queryCommandState(cmd))); 
    4826           } catch (e) {} 
    4827       } 
     5007          }  
     5008                                catch (e)  
     5009                                        {} 
     5010 
     5011                                break; 
     5012 
     5013                        }       // end of switch 
    48285014 
    48295015    } // end of for loop over toolbar objects 
     
    48365022    var editor = this; 
    48375023    this._timerUndo = setTimeout(function()  
    4838            { 
     5024                        { 
    48395025      editor._timerUndo = null; 
    48405026      }, this.config.undoTimeout); 
     
    57545940 
    57555941  this._popupDialog(editor.config.URIs["insert_image"], function(param)  
    5756     { 
     5942                { 
    57575943    if (!param)  
    5758            {    // user must have pressed Cancel 
     5944                        {       // user must have pressed Cancel 
    57595945      return false; 
    57605946      } 
    57615947 
    57625948    var img = image; 
     5949 
    57635950    if (!img)  
    5764            { 
     5951                        { 
    57655952      var sel = editor._getSelection(); 
    57665953      var range = editor._createRange(sel); 
     5954 
    57675955      editor._doc.execCommand("insertimage", false, param.f_url); 
     5956 
    57685957      if (HTMLArea.is_ie)  
    5769                   { 
     5958                                { 
    57705959        img = range.parentElement(); 
     5960 
    57715961        // wonder if this works... 
     5962 
    57725963        if (img.tagName.toLowerCase() != "img")  
    5773                     { 
    5774           img = img.previousSibling; 
     5964                            { 
     5965                                        img = img.previousSibling; 
    57755966          } 
    57765967        }  
    5777                 else  
    5778                   { 
     5968                        else  
     5969                          { 
    57795970        img = range.startContainer.previousSibling; 
    57805971        } 
    57815972      }  
    5782          else  
    5783            { 
     5973                else  
     5974                        { 
    57845975      img.src = param.f_url; 
    57855976      } 
    57865977 
    5787     for (var field in param)  
    5788            { 
     5978                for (var field in param)  
     5979                        { 
    57895980      var value = param[field]; 
    57905981      switch (field)  
     
    59546145  switch (cmdID)  
    59556146    { 
    5956     case "htmlmode" : this.setMode(); break; 
     6147    case "htmlmode" :  
     6148                 
     6149                        this.ddt._ddtDumpNode( "htmlarea.js", "5978", "execCommand(): htmlmode command. Switching modes. Current document is:", this._doc.body ); 
     6150                        this.setMode();  
     6151 
     6152                        this.ddt._ddtDumpNode( "htmlarea.js", "5978", "execCommand(): htmlmode command. after switch. Document is:", this._doc.body ); 
     6153 
     6154                        break; 
     6155 
    59576156    case "hilitecolor": 
    59586157      (HTMLArea.is_ie) && (cmdID = "backcolor"); 
     
    59626161                  { 
    59636162        if (color)  
    5964                     { // selection not canceled 
     6163                                        { // selection not canceled 
    59656164          editor._doc.execCommand(cmdID, false, "#" + color); 
    59666165          } 
     
    59776176      var win; 
    59786177      if (HTMLArea.is_ie)  
    5979                   { 
     6178                                { 
    59806179          { 
    59816180          win = window.open(this.popupURL(editor.config.URIs["fullscreen"]), "ha_fullscreen", 
    59826181              "toolbar=no,location=no,directories=no,status=no,menubar=no," + 
    59836182              "scrollbars=no,resizable=yes,width=640,height=480"); 
    5984            } 
     6183          } 
    59856184        }  
    5986                 else  
    5987                   { 
     6185                        else  
     6186                        { 
    59886187        win = window.open(this.popupURL(editor.config.URIs["fullscreen"]), "ha_fullscreen", 
    59896188            "toolbar=no,menubar=no,personalbar=no,width=640,height=480," + 
    59906189            "scrollbars=no,resizable=yes"); 
    59916190        } 
     6191 
    59926192      win.focus() 
    59936193 
     
    60136213    case "paste": 
    60146214      try  
    6015                   { 
     6215                          { 
    60166216        this._doc.execCommand(cmdID, UI, param); 
    60176217        if (this.config.killWordOnPaste) 
    60186218          this._wordClean(); 
    60196219        }  
    6020                 catch (e)  
    6021                   { 
    6022         if (HTMLArea.is_gecko)  
    6023                     { 
    6024           alert(HTMLArea._lc("The Paste button does not work in Mozilla based web browsers (technical security reasons). Press CTRL-V on your keyboard to paste directly.")); 
    6025           } 
    6026         } 
     6220                        catch (e)  
     6221                          { 
     6222                                if (HTMLArea.is_gecko)  
     6223                          { 
     6224                                        alert(HTMLArea._lc("The Paste button does not work in Mozilla based web browsers (technical security reasons). Press CTRL-V on your keyboard to paste directly.")); 
     6225                                        } 
     6226                                } 
    60276227      break; 
    60286228 
     
    60366236 
    60376237      if (el)  
    6038                   { 
     6238                          { 
    60396239        if (el.style.direction == dir) 
    60406240          el.style.direction = ""; 
     
    60466246 
    60476247    default:  
    6048            try  
    6049                   {  
    6050                   this._doc.execCommand(cmdID, UI, param);  
    6051                   } 
     6248 
     6249                this.ddt._ddt( "htmlarea.js","6119", "execCommand(): passing '" + cmdID + "' to internal browser command handler." ); 
     6250 
     6251                        try  
     6252                          {  
     6253                          this._doc.execCommand(cmdID, UI, param);  
     6254                          } 
    60526255      catch(e)  
    6053                   {  
    6054                   if (this.config.debug) { alert(e + "\n\nby execCommand(" + cmdID + ");"); }  
    6055                   } 
     6256                          {  
     6257                          if (this.config.debug) { alert(e + "\n\nby execCommand(" + cmdID + ");"); }  
     6258                          } 
    60566259 
    60576260    }  // end of switch. 
     
    60666269 
    60676270/**  
    6068 * _editoEvent() 
     6271* _editorEvent() 
    60696272* 
    60706273* A generic event handler for things that happen in the IFRAME's document. 
     
    60976300    } 
    60986301 
    6099   if (keyEvent) 
    6100     { 
     6302        if (keyEvent) 
     6303                { 
    61016304 
    61026305    this.ddt._ddt( "htmlarea.js","6102", "_editorEvent(): keyEvent" ); 
    61036306 
    6104          // loop over all the plugins and pass this event to any that have  
    6105          // an onKeyPress() method. 
     6307                // loop over all the plugins and pass this event to any that have  
     6308                // an onKeyPress() method. 
    61066309 
    61076310    for (var i in editor.plugins) 
     
    61096312      var plugin = editor.plugins[i].instance; 
    61106313 
    6111       // to make it easier to figure out what kind of object we're talking to 
    6112                 // I've added a name member. This change has not yet been applied to  
    6113                 // all plugins. 
    6114  
    6115            this.ddt._ddtDumpObject( "htmlarea.js","5994", "_editorEvent(): plugin '" + ( plugin.name ? plugin.name : "unknown" ) + "' has members:", plugin ); 
     6314                        // to make it easier to figure out what kind of object we're talking to 
     6315                        // I've added a name member. This change has not yet been applied to  
     6316                        // all plugins. 
     6317 
     6318                        // this.ddt._ddtDumpObject( "htmlarea.js","5994", "_editorEvent(): plugin '" + ( plugin.name ? plugin.name : "unknown" ) + "' has members:", plugin ); 
     6319 
     6320                        this.ddt._ddt( "htmlarea.js","5994", "_editorEvent(): plugin '" + ( plugin.name ? plugin.name : "unknown" ) + "'" ); 
    61166321 
    61176322      if (typeof plugin.onKeyPress == "function") 
    6118                   { 
    6119  
    6120                   this.ddt._ddt( "htmlarea.js","6120", "_editorEvent(): keyEvent - invoking onKeyPress method in plugin '" + ( plugin.name ? plugin.name : "unknown" ) + "'" ); 
     6323                                { 
     6324 
     6325                                this.ddt._ddt( "htmlarea.js","6120", "_editorEvent(): keyEvent - invoking onKeyPress method in plugin '" + ( plugin.name ? plugin.name : "unknown" ) + "'" ); 
    61216326                                                                                                                                                                                                                                                                                                                                  
    61226327        if (plugin.onKeyPress(ev)) 
    61236328          { 
    61246329 
    6125                          this.ddt._ddt( "htmlarea.js","6125", "_editorEvent(): keyEvent - onKeyPress() returned false. Returning false" ); 
     6330                                        this.ddt._ddt( "htmlarea.js","6125", "_editorEvent(): keyEvent - onKeyPress() returned false. Returning false" ); 
    61266331          return false; 
    6127                          } 
     6332                                        } 
    61286333 
    61296334                  } // end of if this plugin had a KeyPress handler. 
     
    63286533          { 
    63296534 
    6330                          this.ddt._ddt( "htmlarea.js","6330", "_editorEvent(): entered a space" ); 
     6535                                        this.ddt._ddt( "htmlarea.js","6330", "_editorEvent(): entered a space" ); 
    63316536 
    63326537          if(s && s.isCollapsed && s.anchorNode.nodeType == 3 && s.anchorNode.data.length > 3 && s.anchorNode.data.indexOf('.') >= 0) 
     
    63716576          { 
    63726577 
    6373                          this.ddt._ddt( "htmlarea.js","6373", "_editorEvent(): keycode is '" + ev.keyCode + "' which (normal key) is '" + ev.which + "'" ); 
    6374  
    6375                          // is it an escape character or ... 
     6578                                        this.ddt._ddt( "htmlarea.js","6373", "_editorEvent(): keycode is '" + ev.keyCode + "' which (normal key) is '" + ev.which + "'" ); 
     6579 
     6580                                        // is it an escape character or ... 
    63766581 
    63776582          if(ev.keyCode == 27 || (this._unlinkOnUndo && ev.ctrlKey && ev.which == 122) ) 
     
    63876592            { 
    63886593 
    6389                                 // backspace or period?  
     6594                                                // backspace or period?  
    63906595 
    63916596            this.ddt._ddt( "htmlarea.js","6391", "_editorEvent(): normal key or backspace or period" ); 
     
    63956600            if(s.anchorNode && s.anchorNode.nodeType == 3) 
    63966601              { 
     6602 
    63976603              // See if we might be changing a link 
    63986604              var a = this._getFirstAncestor(s, 'a'); 
    63996605 
    64006606              if (!a)  
    6401                                     { 
    6402                                          this.ddt._ddt( "htmlarea.js","6402", "_editorEvent(): not an anchor" ); 
    6403                                          break; // not an anchor 
    6404                                          } 
     6607                                                                { 
     6608                                                                this.ddt._ddt( "htmlarea.js","6402", "_editorEvent(): not an anchor" ); 
     6609                                                                break; // not an anchor 
     6610                                                                } 
    64056611 
    64066612              if(!a._updateAnchTimeout) 
     
    64506656      case 13: // KEY enter 
    64516657 
    6452                  this.ddt._ddt( "htmlarea.js","6452", "_editorEvent(): enter key handling" ); 
     6658                                this.ddt._ddt( "htmlarea.js","6452", "_editorEvent(): enter key handling" ); 
    64536659 
    64546660        if (HTMLArea.is_gecko && !ev.shiftKey && this.config.mozParaHandler == 'dirty' ) 
     
    64626668      case 46: // KEY delete 
    64636669 
    6464                  this.ddt._ddt( "htmlarea.js","6464", "_editorEvent(): delete or backspace handling" ); 
     6670                                this.ddt._ddt( "htmlarea.js","6464", "_editorEvent(): delete or backspace handling" ); 
    64656671 
    64666672        if (HTMLArea.is_gecko && !ev.shiftKey)  
    6467                     { 
     6673                        { 
    64686674          if (this.dom_checkBackspace()) 
    64696675            HTMLArea._stopEvent(ev); 
    64706676          }  
    6471                   else if (HTMLArea.is_ie)  
    6472                     { 
     6677                                else if (HTMLArea.is_ie)  
     6678                        { 
    64736679          if (this.ie_checkBackspace()) 
    64746680            HTMLArea._stopEvent(ev); 
    64756681          } 
    64766682        break; 
     6683 
    64776684      } // end of switch 
    64786685    } 
     
    66096816 
    66106817  // Get the insertion point, we'll scrub any highlighted text the user wants rid of while we are there. 
     6818 
    66116819  var sel = this._getSelection(); 
    66126820  var range = this._createRange(sel); 
     
    66156823    { 
    66166824    range.deleteContents(); 
    6617     } 
    6618  
     6825    }  
    66196826  this.deactivateEditor(); 
    66206827 
     
    68587065    case "wysiwyg"  : 
    68597066      { 
     7067 
    68607068      if (!this.config.fullPage) 
     7069                                { 
    68617070        html = HTMLArea.getHTML(this._doc.body, false, this); 
     7071                                } 
    68627072      else 
     7073                                { 
    68637074        html = this.doctype + "\n" + HTMLArea.getHTML(this._doc.documentElement, true, this); 
     7075                                } 
     7076 
    68647077      break; 
    68657078      } 
     
    72347447HTMLArea.prototype._getSelection = function()  
    72357448  { 
     7449 
     7450        this.ddt._ddt( "htmlarea.js", "7242", "_getSelection(): top" ); 
     7451 
    72367452  if (HTMLArea.is_ie)  
    72377453    { 
     
    72637479  else  
    72647480    { 
     7481 
    72657482    this.activateEditor(); 
     7483 
    72667484    if (typeof sel != "undefined")  
    7267            { 
     7485                        { 
    72687486      try  
    7269                   { 
     7487                        { 
     7488 
     7489                          this.ddt._ddt( "htmlarea.js","7277", "_createRange(): attempting to create a range using getRangeAt(0) on current selection." ); 
    72707490        return sel.getRangeAt(0); 
    72717491        }  
    7272                 catch(e)  
    7273                   { 
     7492                        catch(e)  
     7493                          { 
     7494                                this.ddt._ddt( "htmlarea.js","7282", "_createRange(): getRangeAt(0) failed, using createRange" ); 
    72747495        return this._doc.createRange(); 
    72757496        } 
    72767497      }  
    72777498    else  
    7278            { 
     7499                        { 
     7500                        this.ddt._ddt( "htmlarea.js","7292", "_createRange(): creating a new range." ); 
     7501 
    72797502      return this._doc.createRange(); 
    72807503      } 
  • branches/unified_backend/index.html

    r124 r172  
    6666 
    6767</p> 
    68 <h2>Unified Backend Branch - snapshot of 2005-04-24</h2> 
     68<h2>Unified Backend Branch - snapshot of 2005-05-17</h2> 
    6969 
    7070<p> 
     
    101101<ul><li><a href="./docs/index.html">Programmers Documentation</a></li></ul> 
    102102 
    103 <h2>Status - only partially functional.</h2> 
     103<h2>Status - core is now mostly functional.</h2> 
    104104<ul> 
    105 <li>Debug trace messages included in htmlarea.js. </li> 
     105<li>Debug trace messages included in htmlarea.js, linker, imagemanager and enterparagraphs </li> 
    106106<li>Beginnings of code-generated documentation using JSDoc and PHPDoc.</li> 
    107107<li>Beginnings of Configure.php to set up server side environment.</li> 
    108108<li>devutils/ directory containing various scripts</li> 
     109<li>EnterParagraphs should now largely work</li> 
    109110</ul> 
    110111 
    111112<h2>TODO</h2> 
    112113<ul> 
    113 <li>The unified backend.</li> 
    114114<li>JSDoc/PHPDoc headers in all plugins</li> 
    115 <li>trace messages in plugins</li> 
    116 <li>debug trace message panel - to turn trace messages on/off on a plugin by plugin basis</li> 
    117115<li>buildruntime.php script to strip out comments and trace messages</li> 
    118 <li>fix enterparagraph</li> 
    119116</ul> 
    120117 
  • branches/unified_backend/plugins/EnterParagraphs/enter-paragraphs.js

    r84 r172  
    1 // By Adam Wright, for The University of Western Australia 
    2 // 
    3 // Distributed under the same terms as HTMLArea itself. 
    4 // This notice MUST stay intact for use (see license.txt). 
    5  
    6 function EnterParagraphs(editor) { 
    7   this.editor = editor; 
    8   // Activate only if we're talking to Gecko 
    9   if (HTMLArea.is_gecko) 
    10     this.onKeyPress = this.__onKeyPress; 
    11 }; 
    12  
    13 EnterParagraphs._pluginInfo = { 
     1// tabs 2 
     2 
     3/** 
     4* @fileoverview By Adam Wright, for The University of Western Australia 
     5* 
     6* Distributed under the same terms as HTMLArea itself. 
     7* This notice MUST stay intact for use (see license.txt). 
     8* 
     9* Heavily modified by Yermo Lamers of DTLink, LLC, College Park, Md., USA. 
     10* For more info see http://www.areaedit.com 
     11*/ 
     12 
     13/** 
     14* plugin Info 
     15*/ 
     16 
     17EnterParagraphs._pluginInfo =  
     18        { 
    1419  name          : "EnterParagraphs", 
    1520  version       : "1.0", 
     
    1924  sponsor_url   : "http://www.uwa.edu.au/", 
    2025  license       : "htmlArea" 
    21 }; 
     26        }; 
     27 
     28// ------------------------------------------------------------------ 
     29 
     30// "constants" 
     31 
     32/** 
     33* Whitespace Regex 
     34*/ 
     35 
     36EnterParagraphs.prototype._whiteSpace = /^\s*$/; 
     37 
     38/** 
     39* The pragmatic list of which elements a paragraph may not contain 
     40*/ 
     41 
     42EnterParagraphs.prototype._pExclusions = /^(address|blockquote|body|dd|div|dl|dt|fieldset|form|h1|h2|h3|h4|h5|h6|hr|li|noscript|ol|p|pre|table|ul)$/i; 
     43 
     44/** 
     45* elements which may contain a paragraph 
     46*/ 
     47 
     48EnterParagraphs.prototype._pContainers = /^(body|del|div|fieldset|form|ins|map|noscript|object|td|th)$/i; 
     49 
     50/** 
     51* Elements which may not contain paragraphs, and would prefer a break to being split 
     52*/ 
     53 
     54EnterParagraphs.prototype._pBreak = /^(address|pre|blockquote)$/i; 
     55 
     56/** 
     57* Elements which may not contain children 
     58*/ 
     59 
     60EnterParagraphs.prototype._permEmpty = /^(area|base|basefont|br|col|frame|hr|img|input|isindex|link|meta|param)$/i; 
     61 
     62/** 
     63* Elements which count as content, as distinct from whitespace or containers 
     64*/ 
     65 
     66EnterParagraphs.prototype._elemSolid = /^(applet|br|button|hr|img|input|table)$/i; 
     67 
     68/** 
     69* Elements which should get a new P, before or after, when enter is pressed at either end 
     70*/ 
     71 
     72EnterParagraphs.prototype._pifySibling = /^(address|blockquote|del|div|dl|fieldset|form|h1|h2|h3|h4|h5|h6|hr|ins|map|noscript|object|ol|p|pre|table|ul|)$/i; 
     73EnterParagraphs.prototype._pifyForced = /^(ul|ol|dl|table)$/i; 
     74 
     75/** 
     76* Elements which should get a new P, before or after a close parent, when enter is pressed at either end 
     77*/ 
     78 
     79EnterParagraphs.prototype._pifyParent = /^(dd|dt|li|td|th|tr)$/i; 
     80 
     81// --------------------------------------------------------------------- 
     82 
     83/** 
     84* EnterParagraphs Constructor 
     85*/ 
     86 
     87function EnterParagraphs(editor)  
     88        { 
     89 
     90  this.editor = editor; 
     91 
     92        // [STRIP 
     93        // create a ddt debug trace object. There may be multiple editors on  
     94        // the page each EnterParagraphs .. to distinguish which instance 
     95        // is generating the message we tack on the name of the textarea. 
     96 
     97        this.ddt = new DDT( editor._textArea + ":EnterParagraphs Plugin" ); 
     98 
     99        // uncomment to turn on debugging messages. 
     100  
     101        this.ddt._ddtOn(); 
     102 
     103        this.ddt._ddt( "enter-paragraphs.js","23", "EnterParagraphs(): constructor" ); 
     104 
     105        // STRIP] 
     106 
     107  // hook into the event handler to intercept key presses if we are using 
     108        // gecko (Mozilla/FireFox) 
     109 
     110  if (HTMLArea.is_gecko) 
     111                { 
     112                this.ddt._ddt( "enter-paragraphs.js","23", "EnterParagraphs(): we are gecko. Setting event handler." ); 
     113    this.onKeyPress = this.__onKeyPress; 
     114                } 
     115 
     116        };      // end of constructor. 
     117 
     118// ------------------------------------------------------------------ 
    22119 
    23120/** 
     
    30127EnterParagraphs.prototype.name = "EnterParagraphs"; 
    31128 
    32 // Whitespace Regex 
    33 EnterParagraphs.prototype._whiteSpace = /^\s*$/; 
    34 // The pragmatic list of which elements a paragraph may not contain, and which may contain a paragraph 
    35 EnterParagraphs.prototype._pExclusions = /^(address|blockquote|body|dd|div|dl|dt|fieldset|form|h1|h2|h3|h4|h5|h6|hr|li|noscript|ol|p|pre|table|ul)$/i; 
    36 EnterParagraphs.prototype._pContainers = /^(body|del|div|fieldset|form|ins|map|noscript|object|td|th)$/i; 
    37 // Elements which may not contain paragraphs, and would prefer a break to being split 
    38 EnterParagraphs.prototype._pBreak = /^(address|pre|blockquote)$/i; 
    39 // Elements which may not contain children 
    40 EnterParagraphs.prototype._permEmpty = /^(area|base|basefont|br|col|frame|hr|img|input|isindex|link|meta|param)$/i; 
    41 // Elements which count as content, as distinct from whitespace or containers 
    42 EnterParagraphs.prototype._elemSolid = /^(applet|br|button|hr|img|input|table)$/i; 
    43 // Elements which should get a new P, before or after, when enter is pressed at either end 
    44 EnterParagraphs.prototype._pifySibling = /^(address|blockquote|del|div|dl|fieldset|form|h1|h2|h3|h4|h5|h6|hr|ins|map|noscript|object|ol|p|pre|table|ul|)$/i; 
    45 EnterParagraphs.prototype._pifyForced = /^(ul|ol|dl|table)$/i; 
    46 // Elements which should get a new P, before or after a close parent, when enter is pressed at either end 
    47 EnterParagraphs.prototype._pifyParent = /^(dd|dt|li|td|th|tr)$/i; 
    48  
    49 // Gecko's a bit lacking in some odd ways... 
    50 EnterParagraphs.prototype.insertAdjacentElement = function(ref,pos,el) { 
    51  
    52   if ( pos == 'BeforeBegin' ) ref.parentNode.insertBefore(el,ref); 
    53   else if ( pos == 'AfterEnd' ) ref.nextSibling ? ref.parentNode.insertBefore(el,ref.nextSibling) : ref.parentNode.appendChild(el); 
    54   else if ( pos == 'AfterBegin' && ref.firstChild ) ref.insertBefore(el,ref.firstChild); 
    55   else if ( pos == 'BeforeEnd' || pos == 'AfterBegin' ) ref.appendChild(el); 
    56 }; 
    57  
    58 // Passes a global parent node or document fragment to forEachNode 
    59 EnterParagraphs.prototype.forEachNodeUnder = function (top, fn, ltr, init, parm) { 
     129/** 
     130* Gecko's a bit lacking in some odd ways... 
     131*/ 
     132 
     133EnterParagraphs.prototype.insertAdjacentElement = function(ref,pos,el)  
     134        { 
     135 
     136        this.ddt._ddtDumpNode( "enter-paragraphs.js", "122", "insertAdjacentElement(): top with pos '" + pos + "' ref:", ref ); 
     137        this.ddt._ddtDumpNode( "enter-paragraphs.js", "122", "insertAdjacentElement(): top with el:", el ); 
     138 
     139  if ( pos == 'BeforeBegin' )  
     140                { 
     141                ref.parentNode.insertBefore(el,ref); 
     142                } 
     143  else if ( pos == 'AfterEnd' )  
     144                { 
     145                ref.nextSibling ? ref.parentNode.insertBefore(el,ref.nextSibling) : ref.parentNode.appendChild(el); 
     146                } 
     147  else if ( pos == 'AfterBegin' && ref.firstChild )  
     148                { 
     149                ref.insertBefore(el,ref.firstChild); 
     150                } 
     151  else if ( pos == 'BeforeEnd' || pos == 'AfterBegin' )  
     152                { 
     153                ref.appendChild(el); 
     154                } 
     155 
     156        this.ddt._ddtDumpNode( "enter-paragraphs.js", "122", "insertAdjacentElement(): bottom with ref:", ref ); 
     157 
     158        };      // end of insertAdjacentElement() 
     159 
     160// ---------------------------------------------------------------- 
     161 
     162/** 
     163* Passes a global parent node or document fragment to forEachNode 
     164* 
     165* @param root node root node to start search from. 
     166* @param mode string function to apply to each node. 
     167* @param direction string traversal direction "ltr" (left to right) or "rtl" (right_to_left) 
     168* @param init boolean 
     169*/ 
     170 
     171EnterParagraphs.prototype.forEachNodeUnder = function ( root, mode, direction, init )  
     172        { 
     173 
     174        this.ddt._ddtDumpNode( "enter-paragraphs.js", "144", "forEachNodeUnder(): top mode is '" + mode + "' direction is '" + direction + "' starting with root node:", root ); 
    60175 
    61176  // Identify the first and last nodes to deal with 
     177         
    62178  var start, end; 
    63   if ( top.nodeType == 11 && top.firstChild ) { 
    64     start = top.firstChild; 
    65     end = top.lastChild; 
    66   } else start = end = top; 
    67   while ( end.lastChild ) end = end.lastChild; 
    68  
    69   // Pass onto forEachNode 
    70   return this.forEachNode(start, end, fn, ltr, init, parm); 
    71 }; 
    72  
    73 // Throws each node into a function 
    74 EnterParagraphs.prototype.forEachNode = function (left, right, fn, ltr, init, parm) { 
    75  
    76   var xBro = function(elem, ltr) { return ( ltr ? elem.nextSibling : elem.previousSibling ); }; 
    77   var xSon = function(elem, ltr) { return ( ltr ? elem.firstChild : elem.lastChild ); }; 
    78   var walk, lookup, fnVal, ping = init; 
    79  
    80   // Until we've hit the last node 
    81   while ( walk != ltr ? right : left ) { 
    82  
    83     // Progress to the next node 
    84     if ( !walk ) walk = ltr ? left : right; 
    85     else { 
    86       if ( xSon(walk,ltr) ) walk = xSon(walk,ltr); 
    87       else { 
    88         if ( xBro(walk,ltr) ) walk = xBro(walk,ltr); 
    89         else { 
     179 
     180        // nodeType 11 is DOCUMENT_FRAGMENT_NODE which is a container.  
     181 
     182  if ( root.nodeType == 11 && root.firstChild )  
     183                { 
     184    start = root.firstChild; 
     185    end = root.lastChild; 
     186          }  
     187        else  
     188                { 
     189                start = end = root; 
     190                } 
     191 
     192        this.ddt._ddtDumpNode( "enter-paragraphs.js", "144", "forEachNodeUnder(): start node is:", start ); 
     193        this.ddt._ddtDumpNode( "enter-paragraphs.js", "144", "forEachNodeUnder(): initial end node is:", end ); 
     194 
     195        // traverse down the right hand side of the tree getting the last child of the last 
     196        // child in each level until we reach bottom. 
     197  while ( end.lastChild )  
     198                end = end.lastChild; 
     199 
     200        this.ddt._ddtDumpNode( "enter-paragraphs.js", "144", "forEachNodeUnder(): end node after descent is:", end ); 
     201 
     202  return this.forEachNode( start, end, mode, direction, init); 
     203 
     204        };      // end of forEachNodeUnder() 
     205 
     206// ----------------------------------------------------------------------- 
     207 
     208/** 
     209* perform a depth first descent in the direction requested. 
     210* 
     211* @param left_node node "start node" 
     212* @param right_node node "end node" 
     213* @param mode string function to apply to each node. cullids or emptyset. 
     214* @param direction string traversal direction "ltr" (left to right) or "rtl" (right_to_left) 
     215* @param init boolean or object. 
     216*/ 
     217 
     218EnterParagraphs.prototype.forEachNode = function (left_node, right_node, mode, direction, init)  
     219        { 
     220 
     221        this.ddt._ddt( "enter-paragraphs.js", "175", "forEachNode(): top - mode is:" + mode + "' direction '" + direction + "'" ); 
     222        this.ddt._ddtDumpNode( "enter-paragraphs.js", "175", "forEachNode(): top - left node is:", left_node ); 
     223        this.ddt._ddtDumpNode( "enter-paragraphs.js", "175", "forEachNode(): top - right node is:", right_node ); 
     224 
     225        // returns "Brother" node either left or right. 
     226 
     227  var getSibling = function(elem, direction)  
     228                                                        {  
     229                                                        return ( direction == "ltr" ? elem.nextSibling : elem.previousSibling );  
     230                                                        }; 
     231 
     232  var getChild = function(elem, direction)  
     233                                                        {  
     234                                                        return ( direction == "ltr" ? elem.firstChild : elem.lastChild );  
     235                                                        }; 
     236 
     237  var walk, lookup, fnReturnVal; 
     238 
     239        // FIXME: init is a boolean in the emptyset case and an object in  
     240        // the cullids case. Used inconsistently. 
     241                 
     242        var next_node = init; 
     243 
     244        // used to flag having reached the last node. 
     245 
     246        var done_flag = false; 
     247 
     248  // loop ntil we've hit the last node in the given direction. 
     249        // if we're going left to right that's the right_node and visa-versa. 
     250 
     251  while ( walk != direction == "ltr" ? right_node : left_node )  
     252                { 
     253 
     254    // on first entry, walk here is null. So this is how  
     255                // we prime the loop with the first node. 
     256 
     257    if ( !walk )  
     258                        { 
     259                        walk = direction == "ltr" ? left_node : right_node; 
     260 
     261                        this.ddt._ddtDumpNode( "enter-paragraphs.js", "175", "forEachNode(): !walk - current node is:", walk ); 
     262                        } 
     263    else  
     264                        { 
     265 
     266                        // is there a child node? 
     267 
     268      if ( getChild(walk,direction) )  
     269                                { 
     270 
     271                                // descend down into the child. 
     272 
     273                                walk = getChild(walk,direction); 
     274 
     275                                this.ddt._ddtDumpNode( "enter-paragraphs.js", "175", "forEachNode():descending to child node:", walk ); 
     276 
     277                                } 
     278      else  
     279                                { 
     280 
     281                                // is there a sibling node on this level? 
     282 
     283        if ( getSibling(walk,direction) )  
     284                                        { 
     285 
     286                                        // move to the sibling. 
     287 
     288                                        walk = getSibling(walk,direction); 
     289 
     290                                        this.ddt._ddtDumpNode( "enter-paragraphs.js", "175", "forEachNode(): moving to sibling node:", walk ); 
     291 
     292                                        } 
     293        else  
     294                                        { 
    90295          lookup = walk; 
    91           while ( !xBro(lookup,ltr) && lookup != (ltr ? right : left) ) lookup = lookup.parentNode; 
    92           walk = ( lookup.nextSibling ? lookup.nextSibling : lookup ) ; 
    93           if ( walk == right ) break; 
    94     }   }       } 
    95  
    96     fnVal = fn(this, walk, ping, parm, (walk==(ltr?right:left)));       // Throw this node at the wanted function 
    97     if ( fnVal[0] ) return fnVal[1];                                                            // If this node wants us to return, return pong 
    98     if ( fnVal[1] ) ping = fnVal[1];                                                            // Otherwise, set pong to ping, to pass to the next node 
    99   } 
     296 
     297                                        // climb back up the tree until we find a level where we are not the end  
     298                                        // node on the level (i.e. that we have a sibling in the direction 
     299                                        // we are searching) or until we reach the end. 
     300 
     301          while ( !getSibling(lookup,direction) && lookup != (direction == "ltr" ? right_node : left_node) )  
     302                                                { 
     303                                                lookup = lookup.parentNode; 
     304                                                } 
     305 
     306                                        // did we find a level with a sibling?  
     307 
     308          // walk = ( lookup.nextSibling ? lookup.nextSibling : lookup ) ; 
     309 
     310          walk = ( getSibling(lookup,direction) ? getSibling(lookup,direction) : lookup ) ; 
     311 
     312                                        this.ddt._ddtDumpNode( "enter-paragraphs.js", "175", "forEachNode(): climbed back up (or found right node):", walk ); 
     313                                         
     314                            }    
     315                                }        
     316 
     317                        }       // end of else walk. 
     318 
     319                // have we reached the end? either as a result of the top while loop or climbing 
     320                // back out above. 
     321 
     322                done_flag = (walk==( direction == "ltr" ? right_node : left_node)); 
     323 
     324                // call the requested function on the current node. Functions 
     325                // return an array.  
     326                // 
     327                // Possible functions are _fenCullIds, _fenEmptySet 
     328                // 
     329                // The situation is complicated by the fact that sometimes we want to 
     330                // return the base node and sometimes we do not. 
     331                // 
     332                // next_node can be an object (this.takenIds), a node (text, el, etc) or false. 
     333 
     334                this.ddt._ddt( "enter-paragraphs.js", "175", "forEachNode(): calling function" ); 
     335 
     336                switch( mode ) 
     337                        { 
     338 
     339                        case "cullids": 
     340 
     341                fnReturnVal = this._fenCullIds(walk, next_node );        
     342                                break; 
     343 
     344                        case "find_fill": 
     345 
     346                fnReturnVal = this._fenEmptySet(walk, next_node, mode, done_flag);       
     347                                break; 
     348 
     349                        case "find_cursorpoint": 
     350 
     351                fnReturnVal = this._fenEmptySet(walk, next_node, mode, done_flag);       
     352                                break; 
     353 
     354                        } 
     355 
     356                // If this node wants us to return, return next_node 
     357 
     358    if ( fnReturnVal[0] )  
     359                        { 
     360                        this.ddt._ddtDumpNode( "enter-paragraphs.js", "175", "forEachNode(): returning node:", fnReturnVal[1] ); 
     361 
     362                        return fnReturnVal[1];                                                           
     363                        } 
     364 
     365                // are we done with the loop?  
     366 
     367                if ( done_flag ) 
     368                        { 
     369                        break; 
     370                        } 
     371 
     372                // Otherwise, pass to the next node 
     373 
     374    if ( fnReturnVal[1] )  
     375                        { 
     376                        next_node = fnReturnVal[1];                                                              
     377                        } 
     378 
     379          }     // end of while loop 
     380 
     381        this.ddt._ddt( "enter-paragraphs.js", "175", "forEachNode(): returning false." ); 
     382 
    100383  return false; 
    101 }; 
    102  
    103 // forEachNode fn: Find a post-insertion node, only if all nodes are empty, or the first content 
    104 EnterParagraphs.prototype._fenEmptySet = function (parent, node, pong, getCont, last) { 
     384 
     385        };      // end of forEachNode() 
     386 
     387// ------------------------------------------------------------------- 
     388 
     389/** 
     390* Find a post-insertion node, only if all nodes are empty, or the first content 
     391* 
     392* @param node node current node beinge examined. 
     393* @param next_node node next node to be examined. 
     394* @param node string "find_fill" or "find_cursorpoint" 
     395* @param last_flag boolean is this the last node?  
     396*/ 
     397 
     398EnterParagraphs.prototype._fenEmptySet = function( node, next_node, mode, last_flag)  
     399        { 
     400 
     401        this.ddt._ddtDumpNode( "enter-paragraphs.js", "263", "_fenEmptySet() : top with mode '" + mode + "' and last_flag '" + last_flag + "' and node:", node ); 
    105402 
    106403  // Mark this if it's the first base 
    107   if ( !pong && !node.firstChild ) pong = node; 
    108  
    109   // Check for content 
    110   if ( (node.nodeType == 1 && parent._elemSolid.test(node.nodeName)) || 
    111     (node.nodeType == 3 && !parent._whiteSpace.test(node.nodeValue)) || 
    112     (node.nodeType != 1 && node.nodeType != 3) ) { 
    113  
    114     return new Array(true, (getCont?node:false)); 
    115   } 
    116  
    117   // Only return the 'base' node if we didn't want content 
    118   if ( last && !getCont ) return new Array(true, pong); 
    119   return new Array(false, pong); 
    120 }; 
    121  
    122 // forEachNode fn: 
    123 EnterParagraphs.prototype._fenCullIds = function (parent, node, pong, parm, last) { 
     404 
     405  if ( !next_node && !node.firstChild )  
     406                { 
     407                next_node = node; 
     408                } 
     409 
     410  // Is it an element node and is it considered content? (br, hr, etc) 
     411        // or is it a text node that is not just whitespace? 
     412        // or is it not an element node and not a text node? 
     413 
     414  if ( (node.nodeType == 1 && this._elemSolid.test(node.nodeName)) || 
     415    (node.nodeType == 3 && !this._whiteSpace.test(node.nodeValue)) || 
     416    (node.nodeType != 1 && node.nodeType != 3) )  
     417                { 
     418 
     419                this.ddt._ddtDumpNode( "enter-paragraphs.js", "263", "_fenEmptySet() : found content in node:", node ); 
     420 
     421                switch( mode ) 
     422                        { 
     423 
     424                        case "find_fill": 
     425 
     426                                // does not return content. 
     427 
     428                    return new Array(true, false ); 
     429                                breal; 
     430 
     431                        case "find_cursorpoint": 
     432                                 
     433                                // returns content 
     434 
     435                    return new Array(true, node ); 
     436                                break; 
     437 
     438                        } 
     439 
     440          } 
     441 
     442  // In either case (fill or findcursor) we return the base node. The avoids 
     443        // problems in terminal cases (beginning or end of document or container tags) 
     444 
     445  if ( last_flag ) 
     446                { 
     447                this.ddt._ddtDumpNode( "enter-paragraphs.js", "263", "_fenEmptySet() : return 'base' node:", next_node ); 
     448 
     449                return new Array( true, next_node ); 
     450                } 
     451 
     452        this.ddt._ddtDumpNode( "enter-paragraphs.js", "263", "_fenEmptySet() : bottom returning false and :", next_node ); 
     453 
     454  return new Array( false, next_node ); 
     455 
     456        };      // end of _fenEmptySet() 
     457 
     458// ------------------------------------------------------------------------------ 
     459 
     460/** 
     461* remove duplicate Id's.  
     462* 
     463* @param ep_ref enterparagraphs reference to enterparagraphs object 
     464*/ 
     465 
     466EnterParagraphs.prototype._fenCullIds = function ( ep_ref, node, pong )  
     467        { 
     468 
     469        this.ddt._ddt( "enter-paragraphs.js", "299", "_fenCullIds(): top" ); 
    124470 
    125471  // Check for an id, blast it if it's in the store, otherwise add it 
    126   if ( node.id ) pong[node.id] ? node.id = '' : pong[node.id] = true; 
     472 
     473  if ( node.id )  
     474                { 
     475 
     476                this.ddt._ddt( "enter-paragraphs.js", "299", "_fenCullIds(): node '" + node.nodeName + "' has an id '" + node.id + "'" ); 
     477 
     478                pong[node.id] ? node.id = '' : pong[node.id] = true; 
     479                } 
     480 
    127481  return new Array(false,pong); 
    128 }; 
    129  
    130 // Grabs a range suitable for paragraph stuffing 
    131 EnterParagraphs.prototype.processSide = function(rng, left) { 
    132  
    133   var next = function(element, left) { return ( left ? element.previousSibling : element.nextSibling ); }; 
    134   var node = left ? rng.startContainer : rng.endContainer; 
    135   var offset = left ? rng.startOffset : rng.endOffset; 
     482 
     483        }; 
     484 
     485// --------------------------------------------------------------------------------- 
     486 
     487/** 
     488* Grabs a range suitable for paragraph stuffing 
     489* 
     490* @param rng Range 
     491* @param search_direction string "left" or "right"  
     492* 
     493* @todo check blank node issue in roaming loop. 
     494*/ 
     495 
     496EnterParagraphs.prototype.processSide = function( rng, search_direction)  
     497        { 
     498 
     499        this.ddt._ddt( "enter-paragraphs.js", "329", "processSide(): top search_direction == '" + search_direction + "'" ); 
     500 
     501  var next = function(element, search_direction)  
     502                                                        {  
     503                                                        return ( search_direction == "left" ? element.previousSibling : element.nextSibling );  
     504                                                        }; 
     505 
     506  var node = search_direction == "left" ? rng.startContainer : rng.endContainer; 
     507  var offset = search_direction == "left" ? rng.startOffset : rng.endOffset; 
    136508  var roam, start = node; 
     509 
     510        this.ddt._ddtDumpNode( "enter-paragraphs.js", "337", "processSide(): starting with node:", node ); 
    137511 
    138512  // Never start with an element, because then the first roaming node might 
    139513  // be on the exclusion list and we wouldn't know until it was too late 
    140   while ( start.nodeType == 1 && !this._permEmpty.test(start.nodeName) ) start = ( offset ? start.lastChild : start.firstChild ); 
     514 
     515  while ( start.nodeType == 1 && !this._permEmpty.test(start.nodeName) )  
     516                { 
     517                start = ( offset ? start.lastChild : start.firstChild ); 
     518                } 
    141519 
    142520  // Climb the tree, left or right, until our course of action presents itself 
    143   while ( roam = roam ? ( next(roam,left) ? next(roam,left) : roam.parentNode ) : start ) { 
    144  
    145     if ( next(roam,left) ) { 
     521        // 
     522        // if roam is NULL try start. 
     523        // if roam is NOT NULL, try next node in our search_direction 
     524        // If that node is NULL, get our parent node. 
     525        // 
     526        // If all the above turns out NULL end the loop. 
     527        // 
     528        // FIXME: gecko (firefox 1.0.3) - enter "test" into an empty document and press enter. 
     529        // sometimes this loop finds a blank text node, sometimes it doesn't. 
     530 
     531  while ( roam = roam ? ( next(roam,search_direction) ? next(roam,search_direction) : roam.parentNode ) : start ) 
     532                { 
     533 
     534                this.ddt._ddtDumpNode( "enter-paragraphs.js", "357", "processSide(): roaming loop, search_direction is '" + search_direction + "' current node is: ", roam ); 
     535 
     536                // next() is an inline function defined above that returns the next node depending 
     537                // on the direction we're searching. 
     538 
     539    if ( next(roam,search_direction) )  
     540                        { 
     541 
     542                        this.ddt._ddt( "enter-paragraphs.js", "371", "processSide(): Checking next node '" + next(roam,search_direction).NodeName + "' for _pExclusions list." ); 
     543 
    146544      // If the next sibling's on the exclusion list, stop before it 
    147       if ( this._pExclusions.test(next(roam,left).nodeName) ) { 
    148         return this.processRng(rng, left, roam, next(roam,left), (left?'AfterEnd':'BeforeBegin'), true, false); 
    149     } } else { 
     545 
     546      if ( this._pExclusions.test(next(roam,search_direction).nodeName) )  
     547                                { 
     548 
     549                                this.ddt._ddt( "enter-paragraphs.js", "371", "processSide(): Node '" + next(roam,search_direction).NodeName + "' is on the _pExclusions list. Stopping before it." ); 
     550 
     551        return this.processRng(rng, search_direction, roam, next(roam,search_direction), (search_direction == "left"?'AfterEnd':'BeforeBegin'), true, false); 
     552                    }  
     553                        }  
     554                else  
     555                        { 
     556 
     557                        this.ddt._ddt( "enter-paragraphs.js", "371", "processSide(): No next node, examing parent node '" + roam.parentNode.nodeName + "' for containers or exclusions." ); 
     558 
    150559      // If our parent's on the container list, stop inside it 
    151       if (this._pContainers.test(roam.parentNode.nodeName)) { 
    152         return this.processRng(rng, left, roam, roam.parentNode, (left?'AfterBegin':'BeforeEnd'), true, false); 
    153       } 
    154       // If our parent's on the exclusion list, chop without wrapping 
    155       else if (this._pExclusions.test(roam.parentNode.nodeName)) { 
    156         if (this._pBreak.test(roam.parentNode.nodeName)) { 
    157           return this.processRng(rng, left, roam, roam.parentNode, 
    158                             (left?'AfterBegin':'BeforeEnd'), false, (left?true:false)); 
    159         } else { 
    160           return this.processRng(rng, left, (roam = roam.parentNode), 
    161                             (next(roam,left) ? next(roam,left) : roam.parentNode), 
    162               (next(roam,left) ? (left?'AfterEnd':'BeforeBegin') : (left?'AfterBegin':'BeforeEnd')), false, false); 
    163 }       }       }       }       }; 
    164  
    165 // Neighbour and insertion identify where the new node, roam, needs to enter 
    166 // the document; landmarks in our selection will be deleted before insertion 
    167 EnterParagraphs.prototype.processRng = function(rng, left, roam, neighbour, insertion, pWrap, preBr) { 
    168  
    169   var node = left ? rng.startContainer : rng.endContainer; 
    170   var offset = left ? rng.startOffset : rng.endOffset; 
     560 
     561      if (this._pContainers.test(roam.parentNode.nodeName))  
     562                                { 
     563 
     564                                this.ddt._ddt( "enter-paragraphs.js", "371", "processSide(): Parent Node '" + roam.parentNode.nodeName + "' is on the _pContainer list. Stopping inside it." ); 
     565 
     566        return this.processRng(rng, search_direction, roam, roam.parentNode, (search_direction == "left"?'AfterBegin':'BeforeEnd'), true, false); 
     567              } 
     568      else if (this._pExclusions.test(roam.parentNode.nodeName))  
     569                                { 
     570 
     571                                this.ddt._ddt( "enter-paragraphs.js", "371", "processSide(): Parent Node '" + roam.parentNode.nodeName + "' is on the _pExclusion list." ); 
     572 
     573              // chop without wrapping 
     574 
     575        if (this._pBreak.test(roam.parentNode.nodeName))  
     576                                        { 
     577 
     578                                        this.ddt._ddt( "enter-paragraphs.js", "371", "processSide(): Parent Node '" + roam.parentNode.nodeName + "' is on the _pBreak list." ); 
     579 
     580          return this.processRng(rng, search_direction, roam, roam.parentNode, 
     581                            (search_direction == "left"?'AfterBegin':'BeforeEnd'), false, (search_direction == "left" ?true:false)); 
     582                }  
     583                                else  
     584                                        { 
     585 
     586                                        this.ddt._ddt( "enter-paragraphs.js", "371", "processSide(): Parent Node '" + roam.parentNode.nodeName + "' is not on the _pBreak list." ); 
     587 
     588                                        // the next(roam,search_direction) in this call is redundant since we know it's false 
     589                                        // because of the "if next(roam,search_direction)" above. 
     590                                        // 
     591                                        // the final false prevents this range from being wrapped in <p>'s most likely 
     592                                        // because it's already wrapped. 
     593 
     594          return this.processRng(rng,  
     595                                                                                                                                search_direction,  
     596                                                                                                                                (roam = roam.parentNode), 
     597                                            (next(roam,search_direction) ? next(roam,search_direction) : roam.parentNode), 
     598                                                                                      (next(roam,search_direction) ? (search_direction == "left"?'AfterEnd':'BeforeBegin') : (search_direction == "left"?'AfterBegin':'BeforeEnd')),  
     599                                                                                                                                false,  
     600                                                                                                                                false); 
     601                                        }        
     602                                }        
     603                        }        
     604                }        
     605 
     606        this.ddt._ddt( "enter-paragraphs.js", "424", "processSide(): bottom" ); 
     607 
     608        };      // end of processSide() 
     609 
     610// ------------------------------------------------------------------------------ 
     611 
     612/** 
     613* processRng - process Range. 
     614* 
     615* Neighbour and insertion identify where the new node, roam, needs to enter 
     616* the document; landmarks in our selection will be deleted before insertion 
     617* 
     618* @param rn Range original selected range 
     619* @param search_direction string Direction to search in. 
     620* @param roam node  
     621* @param insertion string may be AfterBegin of BeforeEnd 
     622* @return array 
     623*/ 
     624 
     625EnterParagraphs.prototype.processRng = function(rng, search_direction, roam, neighbour, insertion, pWrap, preBr)  
     626        { 
     627 
     628        this.ddt._ddtDumpNode( "enter-paragraphs.js", "398", "processRng(): top - roam arg is:", roam ); 
     629        this.ddt._ddtDumpNode( "enter-paragraphs.js", "398", "processRng(): top - neighbor arg is:", neighbour ); 
     630 
     631        this.ddt._ddt( "enter-paragraphs.js", "398", "processRng(): top - insertion arg is: '" + insertion + "'" ); 
     632 
     633  var node = search_direction == "left" ? rng.startContainer : rng.endContainer; 
     634  var offset = search_direction == "left" ? rng.startOffset : rng.endOffset; 
     635 
     636        this.ddt._ddtDumpNode( "enter-paragraphs.js", "447", "processRng(): range start (or end) is at offset '" + offset + "' is node :", node ); 
    171637 
    172638  // Define the range to cut, and extend the selection range to the same boundary 
     639 
    173640  var editor = this.editor; 
    174641  var newRng = editor._doc.createRange(); 
     642 
    175643  newRng.selectNode(roam); 
    176   if (left) { 
     644 
     645        this.ddt._ddtDumpNode( "enter-paragraphs.js", "522", "processRng(): selecting newRng is:", newRng ); 
     646        this.ddt._ddtDumpNode( "enter-paragraphs.js", "522", "processRng(): selecting original rng is:", rng ); 
     647 
     648        // extend the range in the given direction. 
     649 
     650  if ( search_direction == "left") 
     651                { 
    177652    newRng.setEnd(node, offset); 
    178653    rng.setStart(newRng.startContainer, newRng.startOffset); 
    179   } else { 
     654 
     655                this.ddt._ddtDumpNode( "enter-paragraphs.js", "522", "processRng(): extending direction left - newRng is:", newRng ); 
     656                this.ddt._ddtDumpNode( "enter-paragraphs.js", "522", "processRng(): extending direction left - rng is:", rng ); 
     657 
     658          }  
     659        else if ( search_direction == "right" ) 
     660                { 
     661 
    180662    newRng.setStart(node, offset); 
    181     rng.setEnd(newRng.endContainer, newRng.endOffset); 
    182   } 
     663                rng.setEnd(newRng.endContainer, newRng.endOffset); 
     664 
     665                this.ddt._ddt( "enter-paragraphs.js", "522", "processRng(): right - new range start is '" + offset + "' end offset is '" + newRng.endOffset + "'" ); 
     666          } 
     667 
     668        this.ddt._ddtDumpNode( "enter-paragraphs.js", "522", "processRng(): rng is:", rng ); 
     669        this.ddt._ddtDumpNode( "enter-paragraphs.js", "522", "processRng(): newRng is:", newRng ); 
    183670 
    184671  // Clone the range and remove duplicate ids it would otherwise produce 
     672 
    185673  var cnt = newRng.cloneContents(); 
    186   this.forEachNodeUnder(cnt, this._fenCullIds, true, this.takenIds, false); 
    187  
    188   // Special case, for inserting paragraphs before some blocks when caret is at their zero offset 
     674 
     675        this.ddt._ddtDumpNode( "enter-paragraphs.js", "509", "processRng(): culling duplicate ids from:", cnt ); 
     676 
     677        // in this case "init" is an object not a boolen. 
     678 
     679  this.forEachNodeUnder( cnt, "cullids", "ltr", this.takenIds, false, false); 
     680 
     681  // Special case, for inserting paragraphs before some blocks when caret is at  
     682        // their zero offset.  
     683        // 
     684        // Used to "open up space" in front of a list, table. Usefull if the list is at 
     685        // the top of the document. (otherwise you'd have no way of "moving it down"). 
     686 
    189687  var pify, pifyOffset, fill; 
    190   pify = left ? (newRng.endContainer.nodeType == 3 ? true:false) : (newRng.startContainer.nodeType == 3 ? false:true); 
     688  pify = search_direction == "left" ? (newRng.endContainer.nodeType == 3 ? true:false) : (newRng.startContainer.nodeType == 3 ? false:true); 
    191689  pifyOffset = pify ? newRng.startOffset : newRng.endOffset; 
    192690  pify = pify ? newRng.startContainer : newRng.endContainer; 
    193691 
    194   if ( this._pifyParent.test(pify.nodeName) && pify.parentNode.childNodes.item(0) == pify ) { 
    195     while ( !this._pifySibling.test(pify.nodeName) ) pify = pify.parentNode; 
    196   } 
    197  
    198   if ( cnt.nodeType == 11 && !cnt.firstChild ) cnt.appendChild(editor._doc.createElement(pify.nodeName)); 
    199   fill = this.forEachNodeUnder(cnt,this._fenEmptySet,true,false,false); 
    200  
    201   if ( fill && this._pifySibling.test(pify.nodeName) && 
    202     ( (pifyOffset == 0) || ( pifyOffset == 1 && this._pifyForced.test(pify.nodeName) ) ) ) { 
    203  
    204     roam = editor._doc.createElement('p'); 
    205     roam.appendChild(editor._doc.createElement('br')); 
    206  
    207     if (left && pify.previousSibling) return new Array(pify.previousSibling, 'AfterEnd', roam); 
    208     else if (!left && pify.nextSibling) return new Array(pify.nextSibling, 'BeforeBegin', roam); 
    209     else return new Array(pify.parentNode, (left?'AfterBegin':'BeforeEnd'), roam); 
    210   } 
     692        this.ddt._ddtDumpNode( "enter-paragraphs.js", "521", "processRng(): pify is '" + pify.nodeName + "' pifyOffset is '" + pifyOffset + "':", pify ); 
     693 
     694  if ( this._pifyParent.test(pify.nodeName) && pify.parentNode.childNodes.item(0) == pify )  
     695                { 
     696    while ( !this._pifySibling.test(pify.nodeName) )  
     697                        { 
     698                        pify = pify.parentNode; 
     699                        } 
     700          } 
     701 
     702        // NODE TYPE 11 is DOCUMENT_FRAGMENT NODE 
     703 
     704  if ( cnt.nodeType == 11 && !cnt.firstChild )  
     705                { 
     706                cnt.appendChild(editor._doc.createElement(pify.nodeName)); 
     707                } 
     708 
     709        // YmL: Added additional last parameter for fill case to work around logic 
     710        // error in forEachNode() 
     711 
     712        this.ddt._ddt( "enter-paragraphs.js", "612", "processRng(): find_fill in cnt." ); 
     713 
     714  fill = this.forEachNodeUnder(cnt, "find_fill", "ltr", false ); 
     715 
     716        this.ddt._ddtDumpNode( "enter-paragraphs.js", "612", "processRng(): fill node:" , fill ); 
     717 
     718  if ( fill &&  
     719                                this._pifySibling.test(pify.nodeName) && 
     720                ( (pifyOffset == 0) || ( pifyOffset == 1 && this._pifyForced.test(pify.nodeName) ) ) )  
     721                { 
     722 
     723                this.ddt._ddt( "enter-paragraphs.js", "544", "processRng(): pify handling. Creating p tag followed by nbsp tag" ); 
     724 
     725                roam = editor._doc.createElement( 'p' ); 
     726                roam.innerHTML = "&nbsp;"; 
     727 
     728    // roam = editor._doc.createElement('p'); 
     729    // roam.appendChild(editor._doc.createElement('br')); 
     730 
     731                // for these cases, if we are processing the left hand side we want it to halt 
     732                // processing instead of doing the right hand side. (Avoids adding another <p>&nbsp</p> 
     733                // after the list etc. 
     734 
     735    if ((search_direction == "left" ) && pify.previousSibling)  
     736                        { 
     737 
     738                        this.ddt._ddt( "enter-paragraphs.js", "682", "processRng(): returning created roam AfterEnd" ); 
     739 
     740                        return new Array(pify.previousSibling, 'AfterEnd', roam); 
     741                        } 
     742    else if (( search_direction == "right") && pify.nextSibling)  
     743                        { 
     744 
     745                        this.ddt._ddt( "enter-paragraphs.js", "682", "processRng(): returning created roam BeforeBegin" ); 
     746 
     747                        return new Array(pify.nextSibling, 'BeforeBegin', roam); 
     748                        } 
     749    else  
     750                        { 
     751 
     752                        this.ddt._ddt( "enter-paragraphs.js", "682", "processRng(): returning created roam for direction '" + search_direction + "'" ); 
     753 
     754                        return new Array(pify.parentNode, (search_direction == "left"?'AfterBegin':'BeforeEnd'), roam); 
     755                        } 
     756 
     757          } 
    211758 
    212759  // If our cloned contents are 'content'-less, shove a break in them 
    213   if ( fill ) { 
    214     if ( fill.nodeType == 3 ) fill = fill.parentNode;           // Ill-concieved? 
    215     if ( (fill.nodeType == 1 && !this._elemSolid.test()) || fill.nodeType == 11 ) fill.appendChild(editor._doc.createElement('br')); 
    216     else fill.parentNode.insertBefore(editor._doc.createElement('br'),fill); 
    217   } 
    218  
    219   // And stuff a shiny new object with whatever contents we have 
    220   roam = (pWrap || (cnt.nodeType == 11 && !cnt.firstChild)) ? editor._doc.createElement('p') : editor._doc.createDocumentFragment(); 
    221   roam.appendChild(cnt); 
    222   if (preBr) roam.appendChild(editor._doc.createElement('br')); 
     760 
     761  if ( fill )  
     762                { 
     763 
     764                // Ill-concieved?  
     765                // 
     766                // 3 is a TEXT node and it should be empty. 
     767                //  
     768 
     769                if ( fill.nodeType == 3 )  
     770                        { 
     771                        // fill = fill.parentNode;               
     772 
     773                        fill = editor._doc.createDocumentFragment(); 
     774 
     775                        this.ddt._ddtDumpNode( "enter-paragraphs.js", "575", "processRng(): fill.nodeType is 3. Moving up to parent:", fill ); 
     776                        } 
     777 
     778    if ( (fill.nodeType == 1 && !this._elemSolid.test()) || fill.nodeType == 11 )  
     779                        { 
     780 
     781                        // FIXME:/CHECKME: When Xinha is switched from WYSIWYG to text mode  
     782                        // HTMLArea.getHTMLWrapper() will strip out the trailing br. Not sure why. 
     783 
     784                        // fill.appendChild(editor._doc.createElement('br')); 
     785 
     786                        var pterminator = editor._doc.createElement( 'p' ); 
     787                        pterminator.innerHTML = "&nbsp;"; 
     788 
     789                        fill.appendChild( pterminator ); 
     790                          
     791                        this.ddt._ddtDumpNode( "enter-paragraphs.js", "583", "processRng(): fill type is 1 and !elemsolid or it's type 11. Appending an nbsp tag:", fill ); 
     792 
     793                        } 
     794    else  
     795                        { 
     796 
     797                        this.ddt._ddt( "enter-paragraphs.js", "583", "processRng(): inserting a br tag before." ); 
     798 
     799                        // fill.parentNode.insertBefore(editor._doc.createElement('br'),fill); 
     800 
     801                        var pterminator = editor._doc.createElement( 'p' ); 
     802                        pterminator.innerHTML = "&nbsp;"; 
     803 
     804                        fill.parentNode.insertBefore(parentNode,fill); 
     805 
     806                        } 
     807          } 
     808 
     809        // YmL: If there was no content replace with fill 
     810        // (previous code did not use fill and we ended up with the 
     811        // <p>test</p><p></p> because Gecko was finding two empty text nodes  
     812        // when traversing on the right hand side of an empty document. 
     813 
     814        if ( fill ) 
     815                { 
     816 
     817                this.ddt._ddtDumpNode( "enter-paragraphs.js", "606", "processRng(): no content. Using fill.", fill ); 
     818 
     819                roam = fill; 
     820                } 
     821        else 
     822                { 
     823          // And stuff a shiny new object with whatever contents we have 
     824 
     825                this.ddt._ddt( "enter-paragraphs.js", "606", "processRng(): creating p tag or document fragment - pWrap is '" + pWrap + "' " ); 
     826         
     827          roam = (pWrap || (cnt.nodeType == 11 && !cnt.firstChild)) ? editor._doc.createElement('p') : editor._doc.createDocumentFragment(); 
     828          roam.appendChild(cnt); 
     829                } 
     830 
     831  if (preBr)  
     832                { 
     833                this.ddt._ddt( "enter-paragraphs.js", "767", "processRng(): appending a br based on preBr flag" ); 
     834 
     835                roam.appendChild(editor._doc.createElement('br')); 
     836                } 
     837 
     838        this.ddt._ddtDumpNode( "enter-paragraphs.js", "606", "processRng(): bottom with roam:", roam ); 
     839        this.ddt._ddtDumpNode( "enter-paragraphs.js", "606", "processRng(): bottom with neighbour:", neighbour ); 
    223840 
    224841  // Return the nearest relative, relative insertion point and fragment to insert 
     842 
    225843  return new Array(neighbour, insertion, roam); 
    226 }; 
    227  
    228 // Called when a key is pressed in the editor 
    229 EnterParagraphs.prototype.__onKeyPress = function(ev) { 
    230  
    231   // If they've hit enter and shift is up, take it 
     844 
     845        };      // end of processRng() 
     846 
     847// ---------------------------------------------------------------------------------- 
     848 
     849/** 
     850* are we an <li> that should be handled by the browser? 
     851* 
     852* there is no good way to "get out of" ordered or unordered lists from Javascript. 
     853* We have to pass the onKeyPress 13 event to the browser so it can take care of 
     854* getting us "out of" the list.  
     855* 
     856* The Gecko engine does a good job of handling all the normal <li> cases except the "press  
     857* enter at the first position" where we want a <p>&nbsp</p> inserted before the list. The 
     858* built-in behavior is to open up a <li> before the current entry (not good). 
     859*  
     860* @param rng Range range. 
     861*/ 
     862 
     863EnterParagraphs.prototype.isNormalListItem = function(rng) 
     864        { 
     865 
     866        this.ddt._ddtDumpNode( "enter-paragraphs.js", "863", "isNormaListItem(): checking rng for list end:", rng ); 
     867 
     868        var node, listNode; 
     869 
     870        node = rng.startContainer; 
     871 
     872        if (( typeof node.nodeName != 'undefined') && 
     873                ( node.nodeName.toLowerCase() == 'li' )) 
     874                { 
     875 
     876                this.ddt._ddt( "enter-paragraphs.js", "863", "isNormaListItem(): node is a list item"); 
     877 
     878                // are we a list item? 
     879 
     880                listNode = node; 
     881                } 
     882        else if (( typeof node.parentNode != 'undefined' ) && 
     883                                ( typeof node.parentNode.nodeName != 'undefined' ) && 
     884                                ( node.parentNode.nodeName.toLowerCase() == 'li' )) 
     885                { 
     886 
     887                this.ddt._ddt( "enter-paragraphs.js", "863", "isNormaListItem(): parent is a list item"); 
     888                         
     889                // our parent is a list item. 
     890 
     891                listNode = node.parentNode; 
     892 
     893                } 
     894        else 
     895                { 
     896                this.ddt._ddt( "enter-paragraphs.js", "863", "isNormaListItem(): not list item"); 
     897 
     898                // neither we nor our parent are a list item. this is not a normal 
     899                // li case. 
     900 
     901                return false; 
     902                } 
     903 
     904        // at this point we have a listNode. Is it the first list item?  
     905 
     906        if ( ! listNode.previousSibling ) 
     907                { 
     908                this.ddt._ddt( "enter-paragraphs.js", "839", "isNormaListItem(): we are the first li." ); 
     909 
     910                // are we on the first character of the first li?  
     911 
     912                if ( rng.startOffset == 0 ) 
     913                        { 
     914                        this.ddt._ddt( "enter-paragraphs.js", "839", "isNormaListItem(): we are on the first character." ); 
     915 
     916                        return false; 
     917                        } 
     918                } 
     919 
     920        this.ddt._ddt( "enter-paragraphs.js", "839", "isNormaListItem(): this is a normal list item case." ); 
     921        return true; 
     922 
     923        };      // end of isNormalListItem() 
     924 
     925// ---------------------------------------------------------------------------------- 
     926/**                                                       
     927* Called when a key is pressed in the editor 
     928*/ 
     929 
     930EnterParagraphs.prototype.__onKeyPress = function(ev)  
     931        { 
     932 
     933        this.ddt._ddt( "enter-paragraphs.js", "517", "__onKeyPress(): top with keyCode '" + ev.keyCode + "'" ); 
     934 
     935  // If they've hit enter and shift is not pressed, handle it 
     936 
    232937  if (ev.keyCode == 13 && !ev.shiftKey && this.editor._iframe.contentWindow.getSelection) 
     938                { 
     939                this.ddt._ddt( "enter-paragraphs.js", "517", "__onKeyPress(): calling handleEnter" ); 
     940 
    233941    return this.handleEnter(ev); 
    234 }; 
    235  
    236 // Handles the pressing of an unshifted enter for Gecko 
    237 EnterParagraphs.prototype.handleEnter = function(ev) { 
     942                } 
     943 
     944        this.ddt._ddt( "enter-paragraphs.js", "517", "__onKeyPress(): bottom" ); 
     945 
     946        };      // end of _onKeyPress() 
     947 
     948// ----------------------------------------------------------------------------------- 
     949 
     950/** 
     951* Handles the pressing of an unshifted enter for Gecko 
     952*/ 
     953 
     954EnterParagraphs.prototype.handleEnter = function(ev)  
     955        { 
     956 
     957        this.ddt._ddt( "enter-paragraphs.js", "537", "handleEnter(): top" ); 
     958 
     959        var cursorNode; 
    238960 
    239961  // Grab the selection and associated range 
     962 
    240963  var sel = this.editor._getSelection(); 
    241964  var rng = this.editor._createRange(sel); 
     965 
     966        this.ddt._ddtDumpNode( "enter-paragraphs.js", "757", "handleEnter(): initial range is: ", rng ); 
     967 
     968        // if we are at the end of a list and the node is empty let the browser handle 
     969        // it to get us out of the list. 
     970 
     971        if ( this.isNormalListItem(rng) ) 
     972                { 
     973                this.ddt._ddt( "enter-paragraphs.js", "757", "handleEnter(): we are at the end of a list with a blank item. Letting the browser handle it." ); 
     974                return true; 
     975                } 
     976 
     977        // as far as I can tell this isn't actually used.  
     978 
    242979  this.takenIds = new Object(); 
    243980 
    244981  // Grab ranges for document re-stuffing, if appropriate 
    245   var pStart = this.processSide(rng, true); 
    246   var pEnd = this.processSide(rng, false); 
     982        // 
     983        // pStart and pEnd are arrays consisting of 
     984        // [0] neighbor node 
     985        // [1] insertion type 
     986        // [2] roam 
     987 
     988        this.ddt._ddt( "enter-paragraphs.js", "537", "handleEnter(): calling processSide on left side." ); 
     989 
     990  var pStart = this.processSide(rng, "left"); 
     991 
     992        this.ddt._ddtDumpNode( "enter-paragraphs.js", "757", "handleEnter(): after processing left side range is: ", rng ); 
     993 
     994        this.ddt._ddt( "enter-paragraphs.js", "537", "handleEnter(): calling processSide on right side." ); 
     995 
     996        var pEnd = this.processSide(rng, "right"); 
     997 
     998        // used to position the cursor after insertion. 
     999 
     1000        cursorNode = pEnd[2]; 
    2471001 
    2481002  // Get rid of everything local to the selection 
     1003 
    2491004  sel.removeAllRanges(); 
    2501005  rng.deleteContents(); 
    2511006 
    252   // Grab a node we'll have after insertion, since fragments will be lost 
    253   var holdEnd = this.forEachNodeUnder(pEnd[2], this._fenEmptySet, true, false, true); 
    254  
    255   // Reinsert our carefully chosen document fragments 
    256   if ( pStart ) this.insertAdjacentElement(pStart[0], pStart[1], pStart[2]); 
    257   if ( pEnd.nodeType != 1 ) this.insertAdjacentElement(pEnd[0], pEnd[1], pEnd[2]); 
     1007        // Grab a node we'll have after insertion, since fragments will be lost 
     1008        // 
     1009        // we'll use this to position the cursor. 
     1010 
     1011        this.ddt._ddt( "enter-paragraphs.js", "712", "handleEnter(): looking for cursor position" ); 
     1012 
     1013  var holdEnd = this.forEachNodeUnder( cursorNode, "find_cursorpoint", "ltr", false, true); 
     1014 
     1015        if ( ! holdEnd ) 
     1016                { 
     1017                alert( "INTERNAL ERROR - could not find place to put cursor after ENTER" ); 
     1018                } 
     1019 
     1020  // Insert our carefully chosen document fragments 
     1021 
     1022  if ( pStart )  
     1023                { 
     1024 
     1025                this.ddt._ddt( "enter-paragraphs.js", "712", "handleEnter(): inserting pEnd" ); 
     1026 
     1027                this.insertAdjacentElement(pStart[0], pStart[1], pStart[2]); 
     1028                } 
     1029 
     1030  if ( pEnd && pEnd.nodeType != 1)  
     1031                { 
     1032 
     1033                this.ddt._ddt( "enter-paragraphs.js", "712", "handleEnter(): inserting pEnd" ); 
     1034 
     1035                this.insertAdjacentElement(pEnd[0], pEnd[1], pEnd[2]); 
     1036                } 
    2581037 
    2591038  // Move the caret in front of the first good text element 
    260   if ( this._permEmpty.test(holdEnd.nodeName) ) { 
     1039 
     1040  if ((holdEnd) && (this._permEmpty.test(holdEnd.nodeName) ))  
     1041                { 
     1042 
     1043                this.ddt._ddt( "enter-paragraphs.js", "712", "handleEnter(): looping to find cursor element." ); 
     1044 
    2611045    var prodigal = 0; 
    262     while ( holdEnd.parentNode.childNodes.item(prodigal) != holdEnd ) prodigal++; 
     1046    while ( holdEnd.parentNode.childNodes.item(prodigal) != holdEnd )  
     1047                        { 
     1048                        prodigal++; 
     1049                        } 
     1050 
    2631051    sel.collapse( holdEnd.parentNode, prodigal); 
    264   } 
    265   else sel.collapse(holdEnd, 0); 
    266   this.editor.scrollToElement(holdEnd); 
     1052          } 
     1053  else  
     1054                { 
     1055 
     1056                // holdEnd might be false. 
     1057 
     1058                try  
     1059                        { 
     1060                        sel.collapse(holdEnd, 0); 
     1061 
     1062                        this.ddt._ddtDumpNode( "enter-paragraphs.js", "1057", "handleEnter(): scrolling to element:", holdEnd ); 
     1063 
     1064                        // interestingly, scrollToElement() scroll so the top if holdEnd is a text node.  
     1065                         
     1066                        if ( holdEnd.nodeType == 3 ) 
     1067                                { 
     1068                                holdEnd = holdEnd.parentNode; 
     1069                                } 
     1070 
     1071                  this.editor.scrollToElement(holdEnd); 
     1072                        } 
     1073                catch (e)  
     1074                        { 
     1075                        // we could try to place the cursor at the end of the document. 
     1076                        } 
     1077                } 
     1078         
    2671079  this.editor.updateToolbar(); 
    2681080 
    269   //====================== 
    270     HTMLArea._stopEvent(ev); 
    271     return true; 
    272 }; 
     1081        HTMLArea._stopEvent(ev); 
     1082 
     1083        return true; 
     1084 
     1085        };      // end of handleEnter() 
     1086 
     1087// END 
  • branches/unified_backend/plugins/ImageManager/backend.php

    r121 r172  
    4141*/ 
    4242 
    43 include_once( "../ddt/ddt.php" ); 
     43include_once( XINHA_INSTALL_ROOT . "/ddt/ddt.php" ); 
    4444 
    4545// uncomment to turn on debugging 
  • branches/unified_backend/plugins/ImageManager/config.inc.php

    r121 r172  
    1 <? 
     1<?php 
    22/** 
    33 * Image Manager configuration file. 
     
    292292// bring in the debugging library. 
    293293 
    294 include_once( XINHA_INSTALL_ROOT . "/ddt/ddt.php" ); 
     294if ( !function_exists( "_ddt" ) ) 
     295        { 
     296        include_once( XINHA_INSTALL_ROOT . "/ddt/ddt.php" ); 
     297        } 
    295298 
    296299// uncomment to send debug messages to a local file 
  • branches/unified_backend/plugins/ImageManager/image-manager.js

    r121 r172  
    9999* then image will contain the selected image. 
    100100* 
    101 * @todo figure out how to get to editor object from Dialog function. 
     101* @todo check previousSibling issue. The fix here is probably covering up some other problem. 
    102102*/ 
    103103 
     
    116116 
    117117                if (image && !/^img$/i.test(image.tagName)) 
     118                        { 
     119                        this.ddt._ddt( "image-manager.js","114", "_insertImage(): setting image to null" ); 
    118120                        image = null; 
     121                        } 
    119122                } 
    120123 
     
    197200                                } 
    198201 
     202                        // pulled in as a result of the closure above. 
     203 
    199204                        var img = image; 
    200205 
     
    204209                                var range = editor._createRange(sel);                    
    205210 
    206                                 ddt._ddt( "image-manager.js","206", "_insertImage(): execing insertImage" ); 
     211                                // this is the browser built-in execCommand, not the HTMLArea execCommand 
     212                                // method. The assumption here is that it will interact with the range 
     213                                // created above so we can pull out the just inserted image from it. 
     214 
     215                                ddt._ddt( "image-manager.js","206", "_insertImage(): no image. invoking browser insertImage execCommand" ); 
    207216 
    208217                                editor._doc.execCommand("insertimage", false, param.f_url); 
     
    221230                                else  
    222231                                        { 
     232 
     233                                        // If the editor window does not have focus or we are positioned immediately  
     234                                        // adjacent to another image and do not have a selection this returns a null  
     235                                        // object, not an img object.  
     236                                        //  
     237                                        // FIXME: The current Xinha commit, #156, does not exibit this behavior and it does 
     238                                        // not have the logic below. This implies there is some other problem elsewhere.  
     239                                        // Why does it return null here under the same circumstances? 
     240 
    223241                                        img = range.startContainer.previousSibling; 
     242 
     243                                        if ( img == null )  
     244                                                { 
     245 
     246                                                // we are probably at the beginning or end of the document. By trial and  
     247                                                // error it looks like the IMG tag is most likely our first child in the 
     248                                                // beginning of document case and under nextSibling in the end of document 
     249                                                // case. We'll need to verify this for future releases of Gecko. 
     250 
     251                                                ddt._ddt( "image-manager.js", "242", "_insertImage(): previousSibling is NULL. Checking firstChild" ); 
     252 
     253                                                if (( range.startContainer.firstChild != null ) && ( range.startContainer.firstChild.nodeName == "IMG" )) 
     254                                                        { 
     255                                                        ddt._ddt( "image-manager.js", "251", "_insertImage(): Found image under firstChild. Beginning of document?" ); 
     256 
     257                                                        img = range.startContainer.firstChild; 
     258                                                        } 
     259                                                else if (( range.startContainer.nextSibling != null ) && ( range.startContainer.nextSibling.nodeName == "IMG" )) 
     260                                                        { 
     261                                                        ddt._ddt( "image-manager.js", "242", "_insertImage(): Found image under nextSibling. end of document?" ); 
     262                                                        img = range.startContainer.nextSibling; 
     263                                                        } 
     264                                                else 
     265                                                        { 
     266                                                        alert( "INTERNAL ERROR - was unable to locate the newly inserted image object. The HTML in the document may be out of whack." ); 
     267                                                        return false 
     268                                                        } 
     269                                                } 
    224270                                        } 
    225271                                }  
     
    228274                                img.src = param.f_url; 
    229275                                } 
    230                  
     276 
     277                        ddt._ddt( "image-manager.js","234", "_insertImage(): before switch type of img is '" + typeof img + "'" ); 
     278                                         
    231279                        for (field in param)  
    232280                                { 
     
    235283                                switch (field)  
    236284                                        { 
    237                                    case "f_alt"    : img.alt     = value; break; 
    238                                    case "f_border" : img.border = parseInt(value || "0"); break; 
    239                                    case "f_align"  : img.align   = value; break; 
    240                                    case "f_vert"   : img.vspace = parseInt(value || "0"); break; 
    241                                    case "f_horiz"  : img.hspace = parseInt(value || "0"); break; 
     285                                        case "f_alt"    : img.alt        = value; break; 
     286                                        case "f_border" : img.border = parseInt(value || "0"); break; 
     287                                        case "f_align"  : img.align      = value; break; 
     288                                        case "f_vert"   : img.vspace = parseInt(value || "0"); break; 
     289                                        case "f_horiz"  : img.hspace = parseInt(value || "0"); break; 
    242290                                        case "f_width"  : img.width = parseInt(value || "0"); break; 
    243291                                        case "f_height"  : img.height = parseInt(value || "0"); break; 
  • branches/unified_backend/plugins/ImageManager/images.php

    r121 r172  
    1 <? 
     1<?php 
     2 
    23/** 
    34 * Show a list of images in a long horizontal table. 
     
    89 
    910require_once('config.inc.php'); 
    10 require_once(XINHA_INSTALL_ROOT . '/ddt/ddt.php'); 
     11 
     12// we may already have a definition of _ddt().  
     13 
     14if ( ! function_exists( "_ddt" ) ) 
     15        { 
     16        require_once(XINHA_INSTALL_ROOT . '/ddt/ddt.php'); 
     17        } 
     18 
    1119require_once('Classes/ImageManager.php'); 
    1220 
     
    1523// _ddtOn(); 
    1624 
    17 //default path is / 
     25_ddt( __FILE__, __LINE__, "images.php - base_url is '" . $IMConfig['base_url'] . "'" ); 
     26 
     27// default path is / 
     28 
    1829$relative = '/'; 
    1930$manager = new ImageManager($IMConfig); 
    2031 
    21 //process any file uploads 
     32// process any file uploads 
     33 
    2234$manager->processUploads(); 
    2335 
     
    2537 
    2638$refreshDir = false; 
    27 //process any directory functions 
     39 
     40// process any directory functions 
     41 
    2842if($manager->deleteDirs() || $manager->processNewDir()) 
    2943        $refreshDir = true; 
    3044 
    31 //check for any sub-directory request 
    32 //check that the requested sub-directory exists 
    33 //and valid 
    34 if(isset($_REQUEST['dir'])) 
    35 { 
     45// check for any sub-directory request 
     46// check that the requested sub-directory exists 
     47// and valid 
     48 
     49if (isset($_REQUEST['dir'])) 
     50        { 
    3651        $path = rawurldecode($_REQUEST['dir']); 
    3752        if($manager->validRelativePath($path)) 
    3853                $relative = $path; 
    39 } 
     54        } 
    4055 
    4156 
    4257$manager = new ImageManager($IMConfig); 
    4358 
    44 //get the list of files and directories 
     59// get the list of files and directories 
     60 
    4561$list = $manager->getFiles($relative); 
    4662 
     
    5066 * Draw the files in an table. 
    5167 */ 
     68 
    5269function drawFiles($list, &$manager) 
    5370{ 
    5471        global $relative; 
    55         global $IMConfig; 
     72 
     73        // we used to have the global $IMConfig here but for some reason the global 
     74        // reference was getting dropped. Pulling it from inside manager is probably 
     75        // cleaner. 
     76 
     77        _ddt( __FILE__, __LINE__, "drawFiles(): config['base_url'] is '" . $manager->config['base_url'] . "'" ); 
    5678 
    5779        foreach($list as $entry => $file)  
     
    6688                <a href="javascript:;" onclick="selectImage('<?php echo $file['relative'];?>', '<?php echo $entry; ?>', <?php echo $file['image'][0];?>, <?php echo $file['image'][1]; ?>);"title="<?php echo $entry; ?> - <?php echo Files::formatSize($file['stat']['size']); ?>"><img src="<?php print $manager->getThumbnail($file['relative']); ?>" alt="<?php echo $entry; ?> - <?php echo Files::formatSize($file['stat']['size']); ?>"/></a> 
    6789                </td></tr><tr><td class="edit"> 
    68                         <a href="<?php echo $IMConfig['backend_url']; ?>__function=images&dir=<?php echo $relative; ?>&amp;delf=<?php echo rawurlencode($file['relative']);?>" title="Trash" onclick="return confirmDeleteFile('<?php echo $entry; ?>');"><img src="<?php print $IMConfig['base_url'];?>img/edit_trash.gif" height="15" width="15" alt="Trash"/></a><a href="javascript:;" title="Edit" onclick="editImage('<?php echo rawurlencode($file['relative']);?>');"><img src="<?php print $IMConfig['base_url'];?>img/edit_pencil.gif" height="15" width="15" alt="Edit"/></a> 
     90                        <a href="<?php print $IMConfig['backend_url']; ?>__function=images&dir=<?php echo $relative; ?>&amp;delf=<?php echo rawurlencode($file['relative']);?>" title="Trash" onclick="return confirmDeleteFile('<?php echo $entry; ?>');"><img src="<?php  
     91                         
     92                        _ddt( __FILE__, __LINE__, "images.php - base_url is '" . $manager->config['base_url'] . "'" ); 
     93                         
     94                        echo $manager->config['base_url'];?>img/edit_trash.gif" height="15" width="15" alt="Trash"/></a><a href="javascript:;" title="Edit" onclick="editImage('<?php echo rawurlencode($file['relative']);?>');"><img src="<?php print $manager->config['base_url'];?>img/edit_pencil.gif" height="15" width="15" alt="Edit"/></a> 
    6995                <?php if($file['image']){ echo $file['image'][0].'x'.$file['image'][1]; } else echo $entry;?> 
    7096                </td></tr></table></td>  
     
    81107{ 
    82108        global $relative; 
    83    global $IMConfig; 
    84109 
    85110        foreach($list as $path => $dir)  
    86111        { ?> 
    87112                <td><table width="100" cellpadding="0" cellspacing="0"><tr><td class="block"> 
    88                 <a href="<?php print $IMConfig['backend_url']; ?>__function=images&dir=<?php echo rawurlencode($path); ?>" onclick="updateDir('<?php echo $path; ?>')" title="<?php echo $dir['entry']; ?>"><img src="<?php print $IMConfig['base_url'];?>img/folder.gif" height="80" width="80" alt="<?php echo $dir['entry']; ?>" /></a> 
     113                <a href="<?php print $manager->config['backend_url']; ?>__function=images&dir=<?php echo rawurlencode($path); ?>" onclick="updateDir('<?php echo $path; ?>')" title="<?php echo $dir['entry']; ?>"><img src="<?php print $manager->config['base_url'];?>img/folder.gif" height="80" width="80" alt="<?php echo $dir['entry']; ?>" /></a> 
    89114                </td></tr><tr> 
    90115                <td class="edit"> 
    91                         <a href="<?php print $IMConfig['backend_url']; ?>__function=editor&dir=<?php echo $relative; ?>&amp;deld=<?php echo rawurlencode($path); ?>" title="Trash" onclick="return confirmDeleteDir('<?php echo $dir['entry']; ?>', <?php echo $dir['count']; ?>);"><img src="<?php print $IMConfig['base_url'];?>img/edit_trash.gif" height="15" width="15" alt="Trash"/></a> 
     116                        <a href="<?php print $$manager->config['backend_url']; ?>__function=editor&dir=<?php echo $relative; ?>&amp;deld=<?php echo rawurlencode($path); ?>" title="Trash" onclick="return confirmDeleteDir('<?php echo $dir['entry']; ?>', <?php echo $dir['count']; ?>);"><img src="<?php  
     117 
     118                        _ddt( __FILE__, __LINE__, "images.php - base_url is '" . $manager->config['base_url'] . "'" ); 
     119                         
     120                        print $manager->config['base_url'];?>img/edit_trash.gif" height="15" width="15" alt="Trash"/></a> 
    92121                        <?php echo $dir['entry']; ?> 
    93122                </td> 
  • branches/unified_backend/plugins/ImageManager/manager.php

    r121 r172  
    1 <? 
     1<?php 
    22/** 
    33* The main GUI for the ImageManager. 
     
    88 
    99require_once('config.inc.php'); 
    10 require_once(XINHA_INSTALL_ROOT . '/ddt/ddt.php'); 
     10 
     11if ( ! function_exists( "_ddt" ) ) 
     12        { 
     13        require_once( XINHA_INSTALL_ROOT . '/ddt/ddt.php'); 
     14        } 
     15 
    1116require_once('Classes/ImageManager.php'); 
    1217         
  • branches/unified_backend/plugins/Linker/linker.js

    r121 r172  
    572572            { 
    573573 
    574                         linker.ddt._ddt( "linker.js","574", "_prepareDialog(): backend defined. loading files using _getback()" ); 
     574                        linker.ddt._ddt( "linker.js","574", "_prepareDialog(): backend defined. loading files using _getback() from '" + linker.lConfig.backend + "__function=scan'" ); 
    575575 
    576576                        //get files from backend 
     
    579579                                                        { 
    580580 
    581                                                         linker.ddt._ddt( "linker.js","581",  "linker.js", "_getback(): got back txt '" + txt + "'"  ); 
     581                                                        // for some reason this linker reference is not working in this closure 
     582                                                        // under firefox 1.0.3. 
     583 
     584                                                        linker.ddt._ddt( "linker.js","581", "_getback(): got back txt '" + txt + "'"  ); 
    582585 
    583586                                                        try  
     
    629632 
    630633  var html = this.html; 
     634 
     635        linker.ddt._ddt( "linker.js","634", "_prepareDialog(): to dialog html '" + html + "'" ); 
    631636 
    632637  // Now we have everything we need, so we can build the dialog. 
  • branches/unified_backend/plugins/Linker/scan.php

    r121 r172  
    278278// get the output in an error popup. 
    279279// 
    280 // _ddtOn(); 
    281  
    282 _ddt( __FILE__, __LINE__, "scan.php: Resulting array is '" + $javascript_array + "'" ); 
     280 
     281_setDebugLog( "/tmp/debug_log.txt" ); 
     282 
     283_ddtOn(); 
     284 
     285_ddt( __FILE__, __LINE__, "scan.php: hello\n" ); 
     286 
     287_ddt( __FILE__, __LINE__, "scan.php: Resulting array is '" . $javascript_array . "'" ); 
    283288 
    284289echo $javascript_array; 
  • branches/unified_backend/popups/about.html

    r124 r172  
    1717this file will match the version of the repository. 
    1818 
    19 [@@82@@] 
     19[@@83@@] 
    2020 
    2121--> 
Note: See TracChangeset for help on using the changeset viewer.