Changeset 546 for branches/mokhet


Ignore:
Timestamp:
08/06/06 04:31:19 (13 years ago)
Author:
mokhet
Message:

add a config variable (config.onDisposeRemoveUI - default false) to choose if the User Interface should be removed
reintroduce inline functions as of the beginning of the branch. But instead of making them anonymous they are now reference with a name
introduce alias compatibily with current trunk events (addDom0Event, prependDom0Event, addEvent, etc.)
transform the generic method HTMLArea.freeLater() to a method in the editor prototype
in HTMLArea.Events.add(), the parameter to force a DOM0 handler is moving from 6th to 4th position. Now it is *add(element, type, handler, forceDom0, scope, arbitraryObject)*
use of the notifier 'dispose' on dispose.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/mokhet/htmlarea.js

    r543 r546  
    8787function HTMLArea(textarea, config) 
    8888{ 
     89  var editor = this; 
    8990  if ( !textarea ) 
    9091  { 
     
    166167    __htmlareas[this.__htmlarea_id_num] = this; 
    167168 
     169    this.toFree = []; 
    168170    this._notifyListeners = {}; 
     171    this.freeLater(this, '_notifyListeners'); 
    169172 
    170173    // Panels 
     
    202205      panels[i].div = panels[i].container; // legacy 
    203206      panels[i].container.className = 'panels ' + i; 
    204 //      HTMLArea.freeLater(panels[i], 'container'); 
    205 //      HTMLArea.freeLater(panels[i], 'div'); 
     207      this.freeLater(panels[i], 'container'); 
     208      this.freeLater(panels[i], 'div'); 
    206209    } 
    207210    // finally store the variable 
    208211    this._panels = panels; 
    209212 
    210 //    HTMLArea.freeLater(this, '_textArea'); 
     213    this.freeLater(this, '_textArea'); 
    211214  } 
    212215} 
     
    556559    btn[0] = HTMLArea._lc(btn[0]); //initialize tooltip 
    557560  } 
     561   
     562  // If set to true, remove the User Interface (iconbar, iframe, statusbar, panels) on dispose 
     563  // If set to false, the User Interface is not changed 
     564  this.onDisposeRemoveUI = false; 
    558565 
    559566}; 
     
    609616    break; 
    610617  } 
     618  return true; 
    611619}; 
    612620 
     
    866874{ 
    867875  this.setLoadingMessage('Create Toolbar'); 
    868   var editor = this;    // to access this in nested functions 
    869876 
    870877  var toolbar = document.createElement("div"); 
     
    874881  toolbar.unselectable = "1"; 
    875882 
    876 //  HTMLArea.freeLater(this, '_toolBar'); 
    877 //  HTMLArea.freeLater(this, '_toolbar'); 
    878    
     883  this.freeLater(this, '_toolBar'); 
     884  this.freeLater(this, '_toolbar'); 
     885 
    879886  var tb_row = null; 
    880887  var tb_objects = {}; 
     888  // wrong case name. Should be this._toolBarObjects according to the comment 5 lines above 
    881889  this._toolbarObjects = tb_objects; 
    882890 
    883         this._createToolbar1(editor, toolbar, tb_objects); 
    884         this._htmlArea.appendChild(toolbar);       
     891        this._createToolbar1(this, toolbar, tb_objects); 
     892        this._htmlArea.appendChild(toolbar); 
    885893   
    886894  return toolbar; 
     
    941949    if ( editor.config.flowToolbars ) 
    942950    { 
    943       if ( HTMLArea.is_ie ) 
    944       { 
    945         table.style.styleFloat = "left"; 
    946       } 
    947       else 
    948       { 
    949         table.style.cssFloat = "left"; 
    950       } 
     951      table.style[ HTMLArea.is_ie ? 'styleFloat' : 'cssFloat'] = "left"; 
    951952    } 
    952953 
     
    10641065      }; 
    10651066       
    1066 //      HTMLArea.freeLater(obj); 
    1067        
     1067      editor.freeLater(obj); 
     1068 
    10681069      tb_objects[txt] = obj; 
    10691070       
     
    10801081        el.appendChild(op); 
    10811082      } 
    1082       HTMLArea.Events.add(el, 'change', HTMLArea.onchange_toolbar_select, editor, [el,txt]); 
     1083      function el_onchange() { editor._comboSelected(el, txt); } 
     1084      HTMLArea.Events.add(el, 'change', el_onchange); 
     1085      editor.notifyOn('dispose', function() { HTMLArea.Events.remove(el, 'change', el_onchange); }); 
    10831086    } 
    10841087    return el; 
     
    11231126        }; 
    11241127       
    1125 //        HTMLArea.freeLater(obj); 
    1126        
     1128        editor.freeLater(obj); 
     1129 
    11271130        tb_objects[txt] = obj; 
    11281131      break; 
     
    11441147      { 
    11451148        name : txt, // the button name (i.e. 'bold') 
    1146         element : el, // the UI element (DIV) 
     1149        element : el, // the UI element (A) 
    11471150        enabled : true, // is it enabled? 
    11481151        active : false, // is it pressed? 
     
    11521155        context : btn[4] || null // enabled in a certain context? 
    11531156      }; 
    1154 //      HTMLArea.freeLater(el); 
    1155 //      HTMLArea.freeLater(obj); 
     1157      editor.freeLater(el); 
     1158      editor.freeLater(obj); 
    11561159 
    11571160      tb_objects[txt] = obj; 
     
    11611164 
    11621165      // handlers to emulate nice flat toolbar buttons 
    1163       HTMLArea.Events.add(el, 'mouseout', HTMLArea.onmouseout_toolbar_button, el, obj); 
    1164  
    1165       HTMLArea.Events.add(el, 'mousedown', HTMLArea.onmousedown_toolbar_button, el, obj); 
    1166  
     1166      function el_onmout() 
     1167      { 
     1168        if ( obj.enabled ) 
     1169        { 
     1170          //HTMLArea._removeClass(el, "buttonHover"); 
     1171          HTMLArea._removeClass(el, "buttonActive"); 
     1172          if ( obj.active ) 
     1173          { 
     1174            HTMLArea._addClass(el, "buttonPressed"); 
     1175          } 
     1176        } 
     1177      } 
     1178      function el_onmdown(ev) 
     1179      { 
     1180        if ( obj.enabled ) 
     1181        { 
     1182          HTMLArea._addClass(el, "buttonActive"); 
     1183          HTMLArea._removeClass(el, "buttonPressed"); 
     1184          HTMLArea.Events.stop(ev); 
     1185        } 
     1186      } 
    11671187      // when clicked, do the following: 
    1168       HTMLArea.Events.add(el, 'click', HTMLArea.onclick_toolbar_button, editor, [el, obj]); 
     1188      function el_onclick(ev) 
     1189      { 
     1190        if ( obj.enabled ) 
     1191        { 
     1192          HTMLArea._removeClass(el, "buttonActive"); 
     1193          //HTMLArea._removeClass(el, "buttonHover"); 
     1194          if ( HTMLArea.is_gecko ) 
     1195          { 
     1196            editor.activateEditor(); 
     1197          } 
     1198          obj.cmd(editor, obj.name, obj); 
     1199          HTMLArea.Events.stop(ev); 
     1200        } 
     1201      } 
     1202      HTMLArea.Events.add(el, 'mouseout', el_onmout); 
     1203      HTMLArea.Events.add(el, 'mousedown', el_onmdown); 
     1204      HTMLArea.Events.add(el, 'click', el_onclick); 
     1205 
     1206      editor.notifyOn('dispose', 
     1207        function() 
     1208        { 
     1209          HTMLArea.Events.remove(el, 'mouseout', el_onmout); 
     1210          HTMLArea.Events.remove(el, 'mousedown', el_onmdown); 
     1211          HTMLArea.Events.remove(el, 'click', el_onclick); 
     1212        } 
     1213      ); 
    11691214 
    11701215      var i_contain = HTMLArea.makeBtnImg(btn[1]); 
     
    12731318  { 
    12741319    doc._htmlareaImgCache = {}; 
    1275 //    HTMLArea.freeLater(doc._htmlareaImgCache); 
    12761320  } 
    12771321 
     
    13431387  statusbar.className = "statusBar"; 
    13441388  this._statusBar = statusbar; 
    1345 //  HTMLArea.freeLater(this, '_statusBar'); 
     1389  this.freeLater(this, '_statusBar'); 
    13461390   
    13471391  // statusbar.appendChild(document.createTextNode(HTMLArea._lc("Path") + ": ")); 
     
    13511395  div.innerHTML = HTMLArea._lc("Path") + ": "; 
    13521396  this._statusBarTree = div; 
    1353 //  HTMLArea.freeLater(this, '_statusBarTree'); 
     1397  this.freeLater(this, '_statusBarTree'); 
    13541398  this._statusBar.appendChild(div); 
    13551399 
     
    13581402  div.style.display = "none"; 
    13591403  this._statusBarTextMode = div; 
    1360 //  HTMLArea.freeLater(this, '_statusBarTextMode'); 
     1404  this.freeLater(this, '_statusBarTextMode'); 
    13611405  this._statusBar.appendChild(div); 
    13621406 
     
    14761520 
    14771521  }; 
    1478 //  HTMLArea.freeLater(this._framework); 
     1522  this.freeLater(this._framework); 
    14791523   
    14801524  var fw = this._framework; 
     
    15231567  var htmlarea = this._framework.table; 
    15241568  this._htmlArea = htmlarea; 
    1525 //  HTMLArea.freeLater(this, '_htmlArea'); 
     1569  this.freeLater(this, '_htmlArea'); 
    15261570  htmlarea.className = "htmlarea"; 
    15271571 
     
    15351579  this._iframe = iframe; 
    15361580  this._iframe.className = 'xinha_iframe'; 
    1537 //  HTMLArea.freeLater(this, '_iframe'); 
     1581  this.freeLater(this, '_iframe'); 
    15381582   
    15391583    // creates & appends the status bar 
     
    15551599  { 
    15561600    // onsubmit get the HTMLArea content and update original textarea. 
    1557     HTMLArea.Events.add(textarea.form, 'submit', HTMLArea.onsubmit_form, this, textarea, 'prepend'); 
    1558  
    1559 //    var initialTAContent = textarea.value; 
     1601    function form_onsubmit() 
     1602    { 
     1603      editor._textArea.value = editor.outwardHtml(editor.getHTML()); 
     1604      return true; 
     1605    } 
     1606    HTMLArea.Events.add(textarea.form, 'submit', form_onsubmit, 'prepend'); 
     1607 
     1608    // this variable should already be saved when the editor was generating 
     1609    var initialTAContent = textarea.value; 
    15601610 
    15611611    // onreset revert the HTMLArea content to the textarea content 
    1562     HTMLArea.Events.add(textarea.form, 'reset', HTMLArea.onreset_form, this, textarea.value, 'prepend'); 
     1612    function form_onreset() 
     1613    { 
     1614      editor.setHTML(editor.inwardHtml(initialTAContent)); 
     1615      editor.updateToolbar(); 
     1616      return true; 
     1617    } 
     1618    HTMLArea.Events.add(textarea.form, 'reset', form_onreset, 'prepend'); 
     1619     
     1620    editor.notifyOn('dispose', 
     1621      function() 
     1622      { 
     1623        HTMLArea.Events.remove(textarea.form, 'submit', form_onsubmit); 
     1624        HTMLArea.Events.remove(textarea.form, 'reset', form_onreset); 
     1625      } 
     1626    ); 
    15631627  } 
    15641628 
    15651629  // add a handler for the "back/forward" case -- on body.unload we save 
    15661630  // the HTML content into the original textarea. 
    1567   HTMLArea.Events.add(window, 'unload', HTMLArea.onunload_backforward, editor, textarea, 'prepend'); 
     1631  function backforward() 
     1632  { 
     1633    textarea.value = editor.outwardHtml(editor.getHTML()); 
     1634    return true; 
     1635  } 
     1636  HTMLArea.Events.add(window, 'unload', backforward, 'prepend'); 
     1637  editor.notifyOn('dispose', function() { HTMLArea.Events.remove(window, 'unload', backforward); } ); 
    15681638 
    15691639  // Hide textarea 
     
    15751645  // Add an event to initialize the iframe once loaded. 
    15761646  editor._iframeLoadDone = false; 
    1577   HTMLArea.Events.add(iframe, 'load', HTMLArea.onload_iframe, this); 
     1647  function iframe_onload() 
     1648  { 
     1649    if ( !editor._iframeLoadDone ) 
     1650    { 
     1651      editor._iframeLoadDone = true; 
     1652      editor.initIframe(); 
     1653    } 
     1654    return true; 
     1655  } 
     1656  HTMLArea.Events.add(iframe, 'load', iframe_onload); 
     1657  editor.notifyOn('dispose', function() { HTMLArea.Events.remove(iframe, 'load', iframe_onload); } ); 
    15781658 
    15791659  return true; 
     
    18601940  { 
    18611941    div.style.width  = this.config.panel_dimensions[side]; 
    1862     if(this._iframe) div.style.height = this._iframe.style.height;      
     1942    if(this._iframe) { div.style.height = this._iframe.style.height; } 
    18631943  } 
    18641944  HTMLArea.addClasses(div, 'panel'); 
     
    20152095  var editor = this; 
    20162096  this.enableToolbar(); 
     2097  return true; 
    20172098}; 
    20182099 
     
    20562137    if ( editor._iframe.contentDocument ) 
    20572138    { 
    2058       this._doc = editor._iframe.contentDocument;         
     2139      this._doc = editor._iframe.contentDocument; 
    20592140    } 
    20602141    else 
     
    20822163  } 
    20832164   
    2084 //  HTMLArea.freeLater(this, '_doc'); 
     2165  this.freeLater(this, '_doc'); 
    20852166   
    20862167  doc.open(); 
     
    21382219 
    21392220  this.setEditorEvents(); 
     2221  return true; 
    21402222}; 
    21412223   
     
    22182300    } 
    22192301  } 
     2302  return true; 
    22202303}; 
    22212304 
     
    22582341    } 
    22592342    this.setEditorEvents(); 
    2260     return true; 
    2261   } 
     2343  } 
     2344  return true; 
    22622345}; 
    22632346 
     
    22712354      var doc = editor._doc; 
    22722355      // if we have multiple editors some bug in Mozilla makes some lose editing ability 
    2273       HTMLArea.Events.add(doc, 'mousedown', editor.activateEditor, editor); 
     2356      HTMLArea.Events.add(doc, 'mousedown', editor.activateEditor, false, editor); 
    22742357 
    22752358      // intercept some events; for updating the toolbar & keyboard handlers 
    2276       HTMLArea.Events.add( 
    2277         doc, 
    2278         ["keydown", "keypress", "mousedown", "mouseup", "drag"], 
    2279         HTMLArea.keymousedrag_doc, 
    2280         editor 
    2281       ); 
     2359      var listener = null; 
     2360      if ( HTMLArea.is_ie ) 
     2361      { 
     2362        listener = function(evt) { editor._editorEvent(editor._iframe.contentWindow.event); }; 
     2363      } 
     2364      else 
     2365      { 
     2366        listener = function(evt) { editor._editorEvent(evt); }; 
     2367      } 
     2368      HTMLArea.Events.add(doc, ["keydown", "keypress", "mousedown", "mouseup", "drag"], listener); 
    22822369 
    22832370      // check if any plugins have registered refresh handlers 
     
    22952382 
    22962383      // on window resize, resize the editor 
    2297       HTMLArea.Events.add(window, 'resize', editor.sizeEditor, editor); 
     2384      HTMLArea.Events.add(window, 'resize', editor.sizeEditor, false, editor); 
     2385 
     2386      editor.notifyOn('dispose', 
     2387        function() 
     2388        { 
     2389          HTMLArea.Events.remove(doc, 'mousedown', editor.activateEditor, editor); 
     2390          HTMLArea.Events.remove(doc, ["keydown", "keypress", "mousedown", "mouseup", "drag"], listener); 
     2391          HTMLArea.Events.remove(window, 'resize', editor.sizeEditor, editor); 
     2392        } 
     2393      ); 
     2394 
    22982395      editor.removeLoadingMessage(); 
    22992396    } 
     
    23602457    alert("Can't register plugin " + plugin.toString() + "."); 
    23612458  } 
     2459  return false; 
    23622460}; 
    23632461 
     
    28802978} 
    28812979 
    2882 HTMLArea.prototype._statusElements = []; 
    28832980// FIXME : this function needs to be splitted in more functions. 
    28842981// It is actually to heavy to be understable and very scary to manipulate 
     
    28862983HTMLArea.prototype.updateToolbar = function(noStatus) 
    28872984{ 
     2985  var editor = this; 
    28882986  var doc = this._doc; 
    28892987  var text = (this._editMode == "textmode"); 
     
    28942992    if ( this.config.statusBar && !noStatus ) 
    28952993    { 
    2896       this.statusBarDispose(true); 
     2994      this.notifyOf('statusbar_dispose'); 
     2995      this._statusBarTree.innerHTML = HTMLArea._lc("Path") + ": "; // clear 
    28972996      for ( var i = ancestors.length; --i >= 0; ) 
    28982997      { 
     
    29083007        var a = document.createElement("a"); 
    29093008        a.href = "#"; 
    2910 //        a.el = el; 
    2911 //        a.editor = this; 
    2912         HTMLArea.Events.add(a, 'click', HTMLArea.onclick_status_updateToolbar, this, a); 
    2913  
    2914         HTMLArea.Events.add(a, 'contextmenu', HTMLArea.oncontextmenu_status, a, el); 
     3009        function a_onclick() 
     3010        { 
     3011          a.blur(); 
     3012          this.selectNodeContents(el); 
     3013          this.updateToolbar(true); 
     3014          return false; 
     3015        } 
     3016        function a_oncmenu() 
     3017        { 
     3018          // TODO: add context menu here 
     3019          a.blur(); 
     3020          var info = "Inline style:\n\n"; 
     3021          info += this.style.cssText.split(/;\s*/).join(";\n"); 
     3022          alert(info); 
     3023          return false; 
     3024        } 
     3025        HTMLArea.Events.add(a, 'click', a_onclick, true, editor); 
     3026        HTMLArea.Events.add(a, 'contextmenu', a_oncmenu, true, el); 
     3027        editor.notifyOn('statusbar_dispose', 
     3028          function() 
     3029          { 
     3030            HTMLArea.Events.remove(a, 'click', a_onclick, editor); 
     3031            HTMLArea.Events.remove(a, 'contextmenu', a_oncmenu, el); 
     3032          } 
     3033        ); 
    29153034 
    29163035        var txt = el.tagName.toLowerCase(); 
     
    29303049          this._statusBarTree.appendChild(document.createTextNode(String.fromCharCode(0xbb))); 
    29313050        } 
    2932         this._statusElements.push(a); 
    29333051      } 
    29343052    } 
     
    29683086          for ( var ka = 0; ka < attrs.length; ++ka ) 
    29693087          { 
     3088            // eval ???? why not using the following line instead ? 
     3089            // if ( !ancestors[k][attrs[ka]] ) 
    29703090            if ( !eval("ancestors[k]." + attrs[ka]) ) 
    29713091            { 
     
    31133233  { 
    31143234    this._undoTakeSnapshot(); 
    3115     var editor = this; 
    31163235    this._timerUndo = setTimeout(function() { editor._timerUndo = null; }, this.config.undoTimeout); 
    31173236  } 
     
    35443663}; 
    35453664 
     3665// Why is this is still in the trunk ? 
     3666// there's no reference to it anywhere else even in plugins 
    35463667HTMLArea.prototype._formatBlock = function(block_format) 
    35473668{ 
     
    37503871    if( range.htmlText ) 
    37513872    { 
    3752       return range.htmlText 
     3873      return range.htmlText; 
    37533874    } 
    37543875    else if(range.length >= 1) 
     
    37863907    if ( link ) 
    37873908    { 
    3788       while (link && !/^a$/i.test(link.tagName)) 
     3909      while ( link && !( /^a$/i.test(link.tagName) ) ) 
    37893910      { 
    37903911        link = link.parentNode; 
     
    38894010      editor.selectNodeContents(a); 
    38904011      editor.updateToolbar(); 
     4012      return true; 
    38914013    }, 
    38924014    outparam); 
     
    39834105        } 
    39844106      } 
     4107      return true; 
    39854108    }, 
    39864109    outparam); 
     
    42904413    if ( String.fromCharCode(ev.charCode).toLowerCase() == 'z' ) 
    42914414    { 
    4292       HTMLArea._stopEvent(ev); 
     4415      HTMLArea.Events.stop(ev); 
    42934416      this._unLink(); 
    42944417      editor.updateToolbar(); 
    4295       return; 
     4418      return false; 
    42964419    } 
    42974420  } 
     
    43304453          range.selectNodeContents(this._doc.body); 
    43314454          sel.addRange(range); 
    4332           HTMLArea._stopEvent(ev); 
     4455          HTMLArea.Events.stop(ev); 
    43334456        } 
    43344457      break; 
     
    43784501      // execute simple command 
    43794502      this.execCommand(cmd, false, value); 
    4380       HTMLArea._stopEvent(ev); 
     4503      HTMLArea.Events.stop(ev); 
    43814504    } 
    43824505  } 
     
    44114534          s.collapse(rightText, 1); 
    44124535        } 
    4413         HTMLArea._stopEvent(ev); 
     4536        HTMLArea.Events.stop(ev); 
    44144537 
    44154538        editor._unLink = function() 
     
    44854608            { 
    44864609              this._unLink(); 
    4487               HTMLArea._stopEvent(ev); 
     4610              HTMLArea.Events.stop(ev); 
    44884611            } 
    44894612            break; 
     
    45134636                    //         This lead to never ending timer if we dont remove this line 
    45144637                    //         But when removed, the email is not correctly updated 
    4515                     a._updateAnchTimeout = setTimeout(fnAnchor, 250); 
     4638                    //a._updateAnchTimeout = setTimeout(fnAnchor, 250); 
    45164639                  }; 
    45174640                  a._updateAnchTimeout = setTimeout(fnAnchor, 1000); 
     
    45254648                  var fnUrl = function() 
    45264649                  { 
    4527                     // @fixme: Alert, sometimes m is undefined becase the url is not an url anymore (was www.url.com and become for example www.url) 
    4528                     var m = txtNode.data.match(HTMLArea.RE_url); 
     4650                    // @fixme: Alert, sometimes tmp is undefined becase the url is not an url anymore (was www.url.com and become for example www.url) 
     4651                    var tmp = txtNode.data.match(HTMLArea.RE_url); 
     4652                    m = tmp ? tmp : m; 
    45294653                    a.href = (m[1] ? m[1] : 'http://') + m[2]; 
    45304654                    // @fixme: why the hell do another timeout is started ? 
    45314655                    //         This lead to never ending timer if we dont remove this line 
    45324656                    //         But when removed, the url is not correctly updated 
    4533                     a._updateAnchTimeout = setTimeout(fnUrl, 250); 
     4657                    //a._updateAnchTimeout = setTimeout(fnUrl, 250); 
    45344658                  }; 
    45354659                  a._updateAnchTimeout = setTimeout(fnUrl, 1000); 
     
    45494673        { 
    45504674          this.dom_checkInsertP(); 
    4551           HTMLArea._stopEvent(ev); 
     4675          HTMLArea.Events.stop(ev); 
    45524676        } 
    45534677      break; 
     
    45584682          if ( this.checkBackspace() ) 
    45594683          { 
    4560             HTMLArea._stopEvent(ev); 
     4684            HTMLArea.Events.stop(ev); 
    45614685          } 
    45624686        } 
     
    45774701    }, 
    45784702    250); 
     4703  return true; 
    45794704}; 
    45804705 
     
    52455370  { 
    52465371    this._notifyListeners[ev] = []; 
    5247 //    HTMLArea.freeLater(this, '_notifyListeners'); 
    52485372  } 
    52495373  this._notifyListeners[ev].push(fn); 
     
    52565380    for ( var i = 0; i < this._notifyListeners[ev].length; i++ ) 
    52575381    { 
    5258       this._notifyListeners[ev][i](ev, args); 
     5382      this._notifyListeners[ev][i].call(this, ev, args); 
    52595383    } 
    52605384  } 
     
    63066430  if ( !el.parentNode ) 
    63076431  { 
    6308     return; 
     6432    return null; 
    63096433  } 
    63106434  var pN = el.parentNode; 
     
    64016525}; 
    64026526 
    6403 HTMLArea.toFree = []; 
    6404 HTMLArea.freeLater = function(obj,prop) 
    6405 { 
    6406 //  HTMLArea.toFree.push({o:obj,p:prop}); 
     6527HTMLArea.prototype.freeLater = function(obj,prop) 
     6528{ 
     6529  this.toFree.push({o:obj,p:prop}); 
    64076530}; 
    64086531 
    64096532/** 
    64106533 * Release memory properties from object 
    6411  * @param {object} O (Object)  The object to free memory 
    6412  * @param (string} P (Property) The property to release (optional) 
     6534 * @param {object} object The object to free memory 
     6535 * @param (string} prop  The property to release (optional) 
    64136536 * @private 
    64146537 */ 
    6415 HTMLArea.free = function(O, P) 
    6416 { 
    6417 /* 
    6418   if ( O && !P ) 
    6419   { 
    6420     for ( var p in O ) 
    6421     { 
    6422       HTMLArea.free(O, p); 
    6423     } 
    6424   } 
    6425   else if ( O ) 
    6426   { 
    6427     // is the try...catch really required here ? 
    6428     try 
    6429     { 
    6430       // if it is the innerHTML property, just do nothing 
    6431       if ( P !== 'innerHTML' ) 
    6432       { 
    6433         // need to unhide TD cells before delete them or they will leak in IE 
    6434         if ( O[P] && O[P].tagName && O[P].tagName.toLowerCase() == 'td' ) 
    6435         { 
    6436           O[P].style.display = ''; 
    6437         } 
    6438         O[P] = null; 
    6439       } 
    6440     } catch(x) {} 
    6441   } 
    6442 */ 
     6538HTMLArea.prototype.free = function(obj, prop) 
     6539{ 
     6540  if ( obj && !prop ) 
     6541  { 
     6542    for ( var p in obj ) 
     6543    { 
     6544      this.free(obj, p); 
     6545    } 
     6546  } 
     6547  else if ( obj && prop != 'innerHTML' ) 
     6548  { 
     6549    try { obj[prop] = null; } catch(x) {} 
     6550  } 
    64436551}; 
    64446552 
     
    64826590   * @param {string | array}       type         Event type to add or indexed array of event types to add 
    64836591   * @param {function}             handler      Event handler 
     6592   * @param {boolean|string}       forceDom0    true if DOM0 model is forced, 'prepend' if DOM0 model is forced and must be prepended to the existings listeners of the same name (optional) default to false 
    64846593   * @param {object}               scope        Execution scope (optional) default to the element reference 
    64856594   * @param {object}               arbitraryObj Arbitrary object provided to the handler (optional) default to null 
    6486    * @param {boolean|string}       forceDom0    true if DOM0 model is forced, 'prepend' if DOM0 model is forced and must be prepended to the existings listeners of the same name (optional) default to false 
    64876595   * @return {boolean} true if the binding is successfull 
    64886596   * @public 
    64896597   */ 
    6490   add : function(element, type, handler, scope, arbitraryObj, forceDom0) 
     6598  add : function(element, type, handler, forceDom0, scope, arbitraryObj) 
    64916599  { 
    64926600    // manage multiple type with an array 
     
    64966604      for ( var j = 0, m = type.length; j < m; j++ ) 
    64976605      { 
    6498         returnValue = HTMLArea.Events.add(element, type[j], handler, scope, arbitraryObj, forceDom0) && returnValue; 
     6606        returnValue = HTMLArea.Events.add(element, type[j], handler, scope, forceDom0, arbitraryObj) && returnValue; 
    64996607      } 
    65006608      return returnValue; 
     
    66266734   * Cancel an event 
    66276735   * @param {Event} evt The event to cancel 
     6736   * @return {boolean} always false 
    66286737   * @public 
    66296738   */ 
     
    66326741    HTMLArea.Events.stopPropagation(evt); 
    66336742    HTMLArea.Events.preventDefault(evt); 
     6743    return false; 
    66346744  }, 
    66356745 
     
    68046914        if ( L ) 
    68056915        { 
    6806           HTMLArea.Events.remove(L[0], L[1], L[2]); 
     6916          HTMLArea.Events.remove(L[0], L[1], L[2], L[4]); 
    68076917        } 
    68086918      } 
     
    68766986/* 
    68776987--------------------------------------------------------------------------- 
    6878   EVENT CALLBACK LISTENERS 
    6879 --------------------------------------------------------------------------- 
    6880 */ 
    6881  
    6882 /** 
    6883  * Callback listener for onchange on a selectbox in the icon toolbar 
    6884  * @param {Event} evt The current event 
    6885  * @param {array} arbitraryObject here : {array} [el,txt] 
    6886  * @scope Xinha instance 
    6887  * @private 
    6888  */ 
    6889 HTMLArea.onchange_toolbar_select = function(evt, arbitraryObject) 
    6890 { 
    6891   this._comboSelected(arbitraryObject[0], arbitraryObject[1]); 
    6892 }; 
    6893  
    6894 /** 
    6895  * Callback listener for onmouseout on an icon in the icon toolbar 
    6896  * @param {Event} evt The current event 
    6897  * @param {array} arbitraryObject here : {object} obj 
    6898  * @scope The icon HTMLElement 
    6899  * @private 
    6900  */ 
    6901 HTMLArea.onmouseout_toolbar_button = function(evt, arbitraryObject) 
    6902 { 
    6903   if ( arbitraryObject.enabled ) 
    6904   { 
    6905     //HTMLArea._removeClass(this, "buttonHover"); 
    6906     HTMLArea._removeClass(this, "buttonActive"); 
    6907     if ( arbitraryObject.active ) 
    6908     { 
    6909       HTMLArea._addClass(this, "buttonPressed"); 
    6910     } 
    6911   } 
    6912 }; 
    6913  
    6914 /** 
    6915  * Callback listener for onmousedown on an icon in the icon toolbar 
    6916  * @param {Event} evt The current event 
    6917  * @param {array} arbitraryObject here : {object} obj 
    6918  * @scope The icon HTMLElement 
    6919  * @private 
    6920  */ 
    6921 HTMLArea.onmousedown_toolbar_button = function(evt, arbitraryObject) 
    6922 { 
    6923   if ( arbitraryObject.enabled ) 
    6924   { 
    6925     HTMLArea._addClass(this, "buttonActive"); 
    6926     HTMLArea._removeClass(this, "buttonPressed"); 
    6927     HTMLArea.Events.stop(evt); 
    6928   } 
    6929 }; 
    6930  
    6931 /** 
    6932  * Callback listener for onclick on an icon in the icon toolbar 
    6933  * @param {Event} evt The current event 
    6934  * @param {array} arbitraryObject here : {array} [el,obj] 
    6935  * @scope Xinha instance 
    6936  * @private 
    6937  */ 
    6938 HTMLArea.onclick_toolbar_button = function(evt, arbitraryObject) 
    6939 { 
    6940   var el = arbitraryObject[0], 
    6941       obj = arbitraryObject[1]; 
    6942   if ( obj.enabled ) 
    6943   { 
    6944     HTMLArea._removeClass(el, "buttonActive"); 
    6945     //HTMLArea._removeClass(el, "buttonHover"); 
    6946     if ( HTMLArea.is_gecko ) 
    6947     { 
    6948       this.activateEditor(); 
    6949     } 
    6950     obj.cmd(this, obj.name, obj); 
    6951     HTMLArea.Events.stop(evt); 
    6952   } 
    6953 }; 
    6954  
    6955 /** 
    6956  * Callback listener for onload of the main iframe 
    6957  * @param {Event} evt The current event 
    6958  * @scope Xinha instance 
    6959  * @private 
    6960  */ 
    6961 HTMLArea.onload_iframe = function(evt) 
    6962 { 
    6963   if ( !this._iframeLoadDone ) 
    6964   { 
    6965     this._iframeLoadDone = true; 
    6966     this.initIframe(); 
    6967   } 
    6968 }; 
    6969  
    6970 /** 
    6971  * Generic callback listeners for ["keydown", "keypress", "mousedown", "mouseup", "drag"] of the iframe document 
    6972  * @param {Event} evt The current event, the event in the iframe for IE 
    6973  * @scope Xinha instance 
    6974  * @private 
    6975  */ 
    6976 if ( HTMLArea.is_ie ) 
    6977 { 
    6978   HTMLArea.keymousedrag_doc = function(evt) { this._editorEvent(this._iframe.contentWindow.event); }; 
    6979 } 
    6980 else 
    6981 { 
    6982   HTMLArea.keymousedrag_doc = function(evt) { this._editorEvent(evt); }; 
    6983 } 
    6984  
    6985 /** 
    6986  * Callback listener for onclick on an element on the statusbar 
    6987  * @param {Event} evt The current event 
    6988  * @param {array} arbitraryObject here : {HTMLElement} the tag A rerefence 
    6989  * @scope Xinha instance 
    6990  * @private 
    6991  */ 
    6992 HTMLArea.onclick_status_updateToolbar = function(evt, arbitraryObject) 
    6993 { 
    6994   arbitraryObject.blur(); 
    6995   this.selectNodeContents(arbitraryObject.el); 
    6996   this.updateToolbar(true); 
    6997   HTMLArea.Events.stop(evt); 
    6998 }; 
    6999  
    7000 /** 
    7001  * Callback listener for oncontextmenu on an element on the statusbar 
    7002  * @param {Event} evt The current event 
    7003  * @param {array} arbitraryObject here : {HTMLElement} the ancestor represented by the tag A 
    7004  * @scope the a tag HTMLElement in the statusbar 
    7005  * @private 
    7006  */ 
    7007 HTMLArea.oncontextmenu_status = function(evt, arbitraryObject) 
    7008 { 
    7009   // TODO: add context menu here 
    7010   this.blur(); 
    7011   var info = "Inline style:\n\n" + arbitraryObject.style.cssText.split(/;\s*/).join(";\n"); 
    7012   HTMLArea.Events.stop(evt); 
    7013 }; 
    7014  
    7015 /** 
    7016  * Callback listener for onsubmit (DOM0 model) on the textarea form 
    7017  * @param {Event} evt The current event 
    7018  * @param {array} arbitraryObject here : {HTMLElement} textarea 
    7019  * @scope Xinha instance 
    7020  * @private 
    7021  */ 
    7022 HTMLArea.onsubmit_form = function(evt, arbitraryObject) 
    7023 { 
    7024   arbitraryObject.value = this.outwardHtml(this.getHTML()); 
    7025   return true; 
    7026 }; 
    7027  
    7028 /** 
    7029  * Callback listener for onreset (DOM0 model) on the textarea form 
    7030  * @param {Event} evt The current event 
    7031  * @param {array} arbitraryObject here : {string} initial textarea value 
    7032  * @scope Xinha instance 
    7033  * @private 
    7034  */ 
    7035 HTMLArea.onreset_form = function(evt, arbitraryObject) 
    7036 { 
    7037   this.setHTML(this.inwardHtml(arbitraryObject)); 
    7038   this.updateToolbar(); 
    7039   return true; 
    7040 }; 
    7041  
    7042 /** 
    7043  * Callback listener for unload (DOM0 model) on the window for the back/forward case 
    7044  * @param {Event} evt The current event 
    7045  * @param {array} arbitraryObject here : {HTMLElement} textarea 
    7046  * @scope Xinha instance 
    7047  * @private 
    7048  */ 
    7049 HTMLArea.onunload_backforward = function(evt, arbitraryObject) 
    7050 { 
    7051   arbitraryObject.value = this.outwardHtml(this.getHTML()); 
    7052   return true; 
    7053 }; 
    7054  
    7055  
    7056 /* 
    7057 --------------------------------------------------------------------------- 
    70586988  HELPERS METHODS 
    70596989--------------------------------------------------------------------------- 
     
    70797009}; 
    70807010 
     7011function alerter(t) 
     7012{ 
     7013  if ( alerter.$ ) 
     7014  { 
     7015    alerter.$ = window.confirm(t); 
     7016  } 
     7017} 
     7018alerter.$ = true; 
     7019 
    70817020/* 
    70827021--------------------------------------------------------------------------- 
     
    70997038HTMLArea.prototype.dispose = function() 
    71007039{ 
    7101   var i, parentNode, Element; 
    7102  
    7103   // specific disposer set by the user 
     7040  var i, parentNode, Element, 
     7041      removeUI = this.config.onDisposeRemoveUI; /* should the user interface be removed ? */ 
     7042 
     7043  // if the editor is activated, it must be deactivated 
     7044  if ( this.editorIsActivated() ) 
     7045  { 
     7046    this.deactivateEditor(); 
     7047  } 
     7048 
     7049  // clear the statusBar 
     7050  this.notifyOf('statusbar_dispose'); 
     7051   
     7052  if ( removeUI ) 
     7053  { 
     7054    // remove the iframe 
     7055    this._iframe.parentNode.removeChild(this._iframe); 
     7056 
     7057    // reinsert the textarea in it's original parent 
     7058    HTMLArea.removeFromParent(this._textArea); 
     7059    this._framework.table.parentNode.insertBefore(this._textArea, this._framework.table); 
     7060 
     7061    // remove the framework 
     7062/* 
     7063    for ( i in this._framework ) 
     7064    { 
     7065      Element = this._framework[i]; 
     7066      parentNode = Element ? Element.parentNode : null; 
     7067      if ( Element && parentNode ) 
     7068      { 
     7069        parentNode.removeChild(Element); 
     7070      } 
     7071      this._framework[i] = null; 
     7072    } 
     7073*/ 
     7074    this._framework.table.parentNode.removeChild(this._framework.table); 
     7075    this._framework = null; 
     7076 
     7077    // try to restore the original size 
     7078    // if the original size failed, we fall off to 100px 
     7079    try { this._textArea.style.width = this._initial_ta_size.w; } catch(x) { this._textArea.style.width = '100px'; } 
     7080    try { this._textArea.style.height = this._initial_ta_size.h; } catch(x) { this._textArea.style.height = '100px'; } 
     7081    this._textArea.style.display = ''; 
     7082  } 
     7083 
     7084  // notify the editor 
     7085  this.notifyOf('dispose', removeUI); 
     7086 
     7087  // call the specific disposer set by the user 
    71047088  this._onDispose(); 
    7105    
    7106   // call the plugins disposer 
    7107   for ( i in this.plugins ) 
    7108   { 
    7109     var plugin = this.plugins[i].instance; 
    7110     if ( plugin && typeof plugin.dispose == "function" ) 
    7111     { 
    7112       plugin.dispose(); 
    7113     } 
    7114   } 
    7115    
    7116   // remove the events 
    7117   HTMLArea.Events.remove(this._doc, 'mousedown', this.activateEditor); 
    7118   HTMLArea.Events.remove(this._doc, ["keydown", "keypress", "mousedown", "mouseup", "drag"], HTMLArea.keymousedrag_doc); 
    7119   HTMLArea.Events.remove(window, 'resize', this.sizeEditor); 
    7120   if ( this._textArea.form ) 
    7121   { 
    7122     HTMLArea.Events.remove(this._textArea.form, 'submit', HTMLArea.onsubmit_form); 
    7123     HTMLArea.Events.remove(this._textArea.form, 'reset', HTMLArea.onreset_form); 
    7124   } 
    7125   HTMLArea.Events.remove(window, 'unload', HTMLArea.onunload_backforward); 
    7126   HTMLArea.Events.remove(this._iframe, 'load', HTMLArea.onload_iframe); 
    7127  
    7128   // dispose the statusbar 
    7129   this.statusBarDispose(false); 
    7130    
    7131   // remove the panels elements 
    7132   for ( i in this._panels ) 
    7133   { 
    7134     // since they are TD cells, we must show them or they will leak in IE 
    7135     // but i cant remember where i have found that, so until i find more information, this part is commented out 
    7136 /* 
    7137     if ( HTMLArea.is_ie ) 
    7138     { 
    7139       this._panels[i].container.style.display = ''; 
    7140     } 
    7141 */ 
    7142     this._panels[i].container = null; 
    7143     this._panels[i].div = null; 
    7144     this._panels[i] = null; 
    7145   } 
    7146  
    7147   // remove the iframe 
    7148   this._iframe.parentNode.removeChild(this._iframe); 
    7149   this._iframe = null; 
    7150  
    7151   // reinsert the textarea in it's original parent 
    7152   HTMLArea.removeFromParent(this._textArea); 
    7153   this._framework.table.parentNode.insertBefore(this._textArea, this._framework.table); 
    7154  
    7155   // remove the framework 
    7156 /* 
    7157   for ( i in this._framework ) 
    7158   { 
    7159     Element = this._framework[i]; 
    7160     parentNode = Element ? Element.parentNode : null; 
    7161     if ( Element && parentNode ) 
    7162     { 
    7163       parentNode.removeChild(Element); 
    7164     } 
    7165     this._framework[i] = null; 
    7166   } 
    7167 */ 
    7168   this._framework.table.parentNode.removeChild(this._framework.table); 
    7169   this._framework = null; 
    7170  
    7171   // remove the reference to the document 
    7172   this._mdoc = null; 
    7173  
    7174   // remove the reference to the HTMLElement textarea 
    7175   // if the original size failed, we fall off to 100px 
    7176   try { this._textArea.style.width = this._initial_ta_size.w; } catch(x) { this._textArea.style.width = '100px'; } 
    7177   try { this._textArea.style.height = this._initial_ta_size.h; } catch(x) { this._textArea.style.height = '100px'; } 
    7178   this._textArea.style.display = ''; 
    7179  
    7180   this._textArea = null; 
     7089 
     7090  // remove the notifyListeners 
     7091//  this._notifyListeners = null; 
     7092 
     7093  // release the variables waiting to be cleared 
     7094  for ( i = this.toFree.length; i--; ) 
     7095  { 
     7096    if ( !this.toFree[i].o ) 
     7097    { 
     7098      alerter("What is " + i + ' ' + this.toFree[i].o); 
     7099    } 
     7100    this.free(this.toFree[i].o, this.toFree[i].p); 
     7101    this.toFree[i].o = null; 
     7102  } 
     7103  this.toFree = null; 
    71817104 
    71827105  // remove reference in the global array 
    71837106  __htmlareas[this.__htmlarea_id_num] = null; 
    7184 }; 
    7185  
    7186 /** 
    7187  * Dispose the elements in the statusbar 
    7188  * @param {boolean} showPath true if "Path: " must be show, false if the content must be emptied 
    7189  * @private 
    7190  */ 
    7191 HTMLArea.prototype.statusBarDispose = function(showPath) 
    7192 { 
    7193   for ( var i = this._statusElements.length; i--; ) 
    7194   { 
    7195     var a = this._statusElements[i]; 
    7196     HTMLArea.Events.remove(a, 'click', HTMLArea.onclick_status_updateToolbar); 
    7197     HTMLArea.Events.remove(a, 'contextmenu', HTMLArea.oncontextmenu_status); 
    7198   } 
    7199   this._statusElements = []; 
    7200   this._statusBarTree.innerHTML = showPath ? HTMLArea._lc("Path") + ": " : ''; // clear 
    72017107}; 
    72027108 
     
    72077113HTMLArea.dispose = function() 
    72087114{ 
     7115  var i; 
    72097116  // Remove every Xinha instances 
    7210   for ( var i = __htmlareas.length; i--; ) 
     7117  for ( i = __htmlareas.length; i--; ) 
    72117118  { 
    72127119    if ( __htmlareas[i] ) 
     
    72157122    } 
    72167123  } 
     7124   
     7125  // remove the images cache 
     7126  for ( i in document._htmlareaImgCache ) 
     7127  { 
     7128    document._htmlareaImgCache[i] = null; 
     7129  } 
     7130  document._htmlareaImgCache = null; 
     7131 
    72177132  // call the event flusher 
    72187133  HTMLArea.Events.flusher(); 
    7219 }; 
     7134   
     7135}; 
     7136 
     7137/* 
     7138--------------------------------------------------------------------------- 
     7139  COMPATIBILITY ALIAS 
     7140--------------------------------------------------------------------------- 
     7141*/ 
     7142 
     7143/** 
     7144 * Adds a standard "DOM-0" event listener to an element. 
     7145 * The DOM-0 events are those applied directly as attributes to 
     7146 * an element - eg element.onclick = stuff; 
     7147 * 
     7148 * By using this function instead of simply overwriting any existing 
     7149 * DOM-0 event by the same name on the element it will trigger as well 
     7150 * as the existing ones.  Handlers are triggered one after the other 
     7151 * in the order they are added. 
     7152 * 
     7153 * Remember to return true/false from your handler, this will determine 
     7154 * whether subsequent handlers will be triggered (ie that the event will 
     7155 * continue or be canceled). 
     7156 * 
     7157 */ 
     7158HTMLArea.addDom0Event = function(el, ev, fn) { return HTMLArea.Events.add(el, ev, fn, true); }; 
     7159 
     7160/** 
     7161 * See addDom0Event, the difference is that handlers registered using 
     7162 * prependDom0Event will be triggered before existing DOM-0 events of the 
     7163 * same name on the same element. 
     7164 */ 
     7165HTMLArea.prependDom0Event = function(el, ev, fn) { return HTMLArea.Events.add(el, ev, fn, 'prepend'); }; 
     7166 
     7167HTMLArea._addEvent = function(el, ev, fn) { return HTMLArea.Events.add(el, ev, fn); }; 
     7168HTMLArea._addEvents = function(el, evs, fn) { return HTMLArea.Events.add(el, evs, fn); }; 
     7169HTMLArea._removeEvent = function(el, ev, fn) { return HTMLArea.Events.remove(el, ev, fn); }; 
     7170HTMLArea._removeEvents = function(el, evs, fn) { return HTMLArea.Events.remove(el, evs, fn); }; 
     7171HTMLArea._stopEvent = function(ev) { return HTMLArea.Events.stop(ev); }; 
    72207172 
    72217173/* 
Note: See TracChangeset for help on using the changeset viewer.