Changeset 674 for trunk


Ignore:
Timestamp:
01/19/07 15:33:17 (13 years ago)
Author:
gogo
Message:

ticket:10 Further work on code separation etc.

Location:
trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/XinhaCore.js

    r673 r674  
    24152415  else 
    24162416  { 
     2417    // FIXME - can we do this without rewriting the entire document 
     2418    //  does the above not work for IE? 
    24172419    var reac = this.editorIsActivated(); 
    24182420    if ( reac ) 
     
    24282430    { 
    24292431      this.activateEditor(); 
    2430     } 
     2432    }         
    24312433    this.setEditorEvents(); 
    24322434    return true; 
     
    24622464      ); 
    24632465 
     2466      // FIXME - this needs to be cleaned up and use editor.firePluginEvent 
     2467      //  I don't like both onGenerate and onGenerateOnce, we should only 
     2468      //  have onGenerate and it should only be called when the editor is  
     2469      //  generated (once and only once) 
    24642470      // check if any plugins have registered refresh handlers 
    24652471      for ( var i in editor.plugins ) 
     
    26592665  } 
    26602666}; 
     2667 
     2668/** Call a method of all plugins which define the method using the supplied arguments. 
     2669 * 
     2670 *  Example: editor.firePluginEvent('onExecCommand', 'paste') 
     2671 *   
     2672 *  The browser specific plugin (if any) is called last.  The result of each call is  
     2673 *  treated as boolean.  A true return means that the event will stop, no further plugins 
     2674 *  will get the event, a false return means the event will continue to fire. 
     2675 * 
     2676 *  @param methodName 
     2677 *  @param arguments to pass to the method, optional [2..n]  
     2678 */ 
     2679 
     2680Xinha.prototype.firePluginEvent = function(methodName) 
     2681{ 
     2682  // arguments is not a real array so we can't just .shift() it unfortunatly. 
     2683  var argsArray = [ ]; 
     2684  for(var i = 1; i < arguments.length; i++) 
     2685  { 
     2686    argsArray[i-1] = arguments[i]; 
     2687  } 
     2688   
     2689  for ( var i in this.plugins ) 
     2690  { 
     2691    var plugin = this.plugins[i].instance; 
     2692     
     2693    // Skip the browser specific plugin 
     2694    if ( plugin == this._browserSpecificPlugin) continue; 
     2695     
     2696    if ( plugin && typeof plugin[methodName] == "function" ) 
     2697    { 
     2698      if ( plugin[methodName].apply(plugin, argsArray) ) 
     2699      { 
     2700        return true; 
     2701      } 
     2702    } 
     2703  } 
     2704   
     2705  // Now the browser speific 
     2706  var plugin = this._browserSpecificPlugin; 
     2707  if ( plugin && typeof plugin[methodName] == "function" ) 
     2708  { 
     2709    if ( plugin[methodName].apply(plugin, argsArray) ) 
     2710    { 
     2711      return true; 
     2712    } 
     2713  } 
     2714     
     2715  return false; 
     2716} 
    26612717 
    26622718Xinha.loadStyle = function(style, plugin) 
     
    33493405  } 
    33503406 
     3407  // FIXME: this should be using this.firePluginEvent('onUpdateToolbar') 
     3408  //   but we have to make sure that the plugins using that event return false 
     3409  //   if they should let the event fire on other plugins, currently the below 
     3410  //   code doesn't take the return value into account 
     3411   
    33513412  // check if any plugins have registered refresh handlers 
    33523413  for ( var indexPlugin in this.plugins ) 
     
    33853446  if ( prnt === null ) 
    33863447  { 
     3448    // Hmm, I think Xinha.getParentElement() would do the job better?? - James 
    33873449    try 
    33883450    { 
     
    37283790  this.focusEditor(); 
    37293791  cmdID = cmdID.toLowerCase(); 
    3730   // useCSS deprecated & replaced by styleWithCSS 
    3731   if ( Xinha.is_gecko ) 
    3732   { 
    3733     try 
    3734     { 
    3735       this._doc.execCommand('useCSS', false, true); //switch useCSS off (true=off) 
    3736       this._doc.execCommand('styleWithCSS', false, false); //switch styleWithCSS off  
    3737        
    3738     } catch (ex) {} 
    3739   } 
     3792   
     3793  // See if any plugins want to do something special 
     3794  if(this.firePluginEvent('onExecCommand', cmdID, UI, param)) 
     3795  { 
     3796    this.updateToolbar(); 
     3797    return false; 
     3798  } 
     3799 
    37403800  switch (cmdID) 
    37413801  { 
     
    37883848    case "copy": 
    37893849    case "paste": 
    3790     try 
    3791     { 
    37923850      this._doc.execCommand(cmdID, UI, param); 
    37933851      if ( this.config.killWordOnPaste ) 
     
    37953853        this._wordClean(); 
    37963854      } 
    3797     } 
    3798     catch (ex) 
    3799     { 
    3800       if ( Xinha.is_gecko ) 
    3801       { 
    3802         alert(Xinha._lc("The Paste button does not work in Mozilla based web browsers (technical security reasons). Press CTRL-V on your keyboard to paste directly.")); 
    3803       } 
    3804     } 
    38053855    break; 
    38063856    case "lefttoright": 
     
    38703920{ 
    38713921  var editor = this; 
    3872   var keyEvent = this.isKeyEvent(ev); 
    38733922 
    38743923  //call events of textarea 
     
    38783927  } 
    38793928   
    3880   if ( keyEvent ) 
     3929  if ( this.isKeyEvent(ev) ) 
    38813930  { 
    38823931    // Run the ordinary plugins first 
    3883     for ( var i in editor.plugins ) 
    3884     { 
    3885       var plugin = editor.plugins[i].instance; 
    3886        
    3887       if ( plugin == editor._browserSpecificPlugin) continue; 
    3888        
    3889       if ( plugin && typeof plugin.onKeyPress == "function" ) 
    3890       { 
    3891         if ( plugin.onKeyPress(ev) ) 
    3892         { 
    3893           return false; 
    3894         } 
    3895       } 
     3932    if(editor.firePluginEvent('onKeyPress', ev)) 
     3933    { 
     3934      return false; 
    38963935    } 
    38973936     
    3898     // Now run the browser specific one 
    3899     if(typeof editor._browserSpecificPlugin.onKeyPress == "function") 
    3900     { 
    3901       if(editor._browserSpecificPlugin.onKeyPress(ev))  
    3902       { 
    3903         return false; 
    3904       } 
    3905     } 
    3906   } 
    3907  
    3908   if ( keyEvent && ev.ctrlKey && !ev.altKey ) 
    3909   { 
    3910         this._shortCuts(ev); 
     3937    // Handle the core shortcuts 
     3938    if ( this.isShortCut( ev ) ) 
     3939    { 
     3940      this._shortCuts(ev); 
     3941    } 
    39113942  } 
    39123943   
     
    39283959Xinha.prototype._shortCuts = function (ev) 
    39293960{ 
    3930   var editor = this; 
    3931   var sel = null; 
    3932   var range = null; 
    3933   var key = String.fromCharCode(Xinha.is_ie ? ev.keyCode : ev.charCode).toLowerCase(); 
     3961  var key = this.getKey(ev).toLowerCase(); 
    39343962  var cmd = null; 
    39353963  var value = null; 
    39363964  switch (key) 
    39373965  { 
    3938     case 'a': 
    3939     if ( !Xinha.is_ie ) 
    3940     { 
    3941       // KEY select all 
    3942       sel = this._getSelection(); 
    3943       sel.removeAllRanges(); 
    3944       range = this._createRange(); 
    3945       range.selectNodeContents(this._doc.body); 
    3946       sel.addRange(range); 
    3947       Xinha._stopEvent(ev); 
    3948     } 
    3949     break; 
    3950  
    39513966    // simple key commands follow 
    39523967 
     
    39613976    case 'z': cmd = "undo"; break; 
    39623977    case 'y': cmd = "redo"; break; 
    3963     case 'v': 
    3964     if ( Xinha.is_ie || editor.config.htmlareaPaste ) 
    3965     { 
    3966       cmd = "paste"; 
    3967     } 
    3968     break; 
     3978    case 'v': cmd = "paste"; break; 
    39693979    case 'n': 
    39703980    cmd = "formatblock"; 
    3971     value = Xinha.is_ie ? "<p>" : "p"; 
     3981    value = "p"; 
    39723982    break; 
    39733983 
     
    39833993    cmd = "formatblock"; 
    39843994    value = "h" + key; 
    3985     if ( Xinha.is_ie ) 
    3986     { 
    3987       value = "<" + value + ">"; 
    3988     } 
    39893995    break; 
    39903996  } 
     
    42284234  } 
    42294235   
    4230   if (1 || Xinha.is_gecko ) 
    4231   { 
    4232     var top  = 0; 
    4233     var left = 0; 
    4234     while ( e ) 
    4235     { 
    4236       top  += e.offsetTop; 
    4237       left += e.offsetLeft; 
    4238       if ( e.offsetParent && e.offsetParent.tagName.toLowerCase() != 'body' ) 
    4239       { 
    4240         e = e.offsetParent; 
    4241       } 
    4242       else 
    4243       { 
    4244         e = null; 
    4245       } 
    4246     } 
    4247     this._iframe.contentWindow.scrollTo(left, top); 
    4248   } 
     4236  // This was at one time limited to Gecko only, but I see no reason for it to be. - James 
     4237  var position = Xinha.getElementTopLeft(e);   
     4238  this._iframe.contentWindow.scrollTo(position.left, position.top); 
    42494239}; 
    42504240 
     
    42774267Xinha.prototype.outwardHtml = function(html) 
    42784268{ 
     4269  for ( var i in this.plugins ) 
     4270  { 
     4271    var plugin = this.plugins[i].instance;     
     4272    if ( plugin && typeof plugin.outwardHtml == "function" ) 
     4273    { 
     4274      html = plugin.outwardHtml(html); 
     4275    } 
     4276  } 
     4277   
    42794278  html = html.replace(/<(\/?)b(\s|>|\/)/ig, "<$1strong$2"); 
    42804279  html = html.replace(/<(\/?)i(\s|>|\/)/ig, "<$1em$2"); 
     
    42884287 
    42894288  // IE puts this in can't figure out why 
     4289  //  leaving this in the core instead of InternetExplorer  
     4290  //  because it might be something we are doing so could present itself 
     4291  //  in other browsers - James  
    42904292  html = html.replace(/https?:\/\/null\//g, serverBase); 
    42914293 
     
    43034305    html = html.replace(/[^ -~\r\n\t]/g, function(c) { return '&#'+c.charCodeAt(0)+';'; }); 
    43044306  } 
    4305  
    4306   // ticket:56, the "greesemonkey" plugin for Firefox adds this junk, 
    4307   // so we strip it out.  Original submitter gave a plugin, but that's 
    4308   // a bit much just for this IMHO - james 
    4309   if ( Xinha.is_gecko ) 
    4310   { 
    4311     html = html.replace(/<script[\s]*src[\s]*=[\s]*['"]chrome:\/\/.*?["']>[\s]*<\/script>/ig, ''); 
    4312   } 
     4307   
    43134308  //prevent execution of JavaScript (Ticket #685) 
    43144309  html = html.replace(/(<script[^>]*)(freezescript)/gi,"$1javascript"); 
     
    43194314    html = Xinha.stripCoreCSS(html); 
    43204315  } 
    4321    
    4322    
     4316     
    43234317  return html; 
    43244318}; 
    43254319 
    43264320Xinha.prototype.inwardHtml = function(html) 
    4327 { 
    4328   // Midas uses b and i instead of strong and em, um, hello, 
    4329   // mozilla, this is the 21st century calling! 
    4330   if ( Xinha.is_gecko ) 
    4331   { 
    4332     html = html.replace(/<(\/?)strong(\s|>|\/)/ig, "<$1b$2"); 
    4333     html = html.replace(/<(\/?)em(\s|>|\/)/ig, "<$1i$2");     
    4334   } 
    4335    
     4321 
     4322  for ( var i in this.plugins ) 
     4323  { 
     4324    var plugin = this.plugins[i].instance;     
     4325    if ( plugin && typeof plugin.inwardHtml == "function" ) 
     4326    { 
     4327      html = plugin.inwardHtml(html); 
     4328    }     
     4329  } 
     4330     
    43364331  // Both IE and Gecko use strike instead of del (#523) 
    43374332  html = html.replace(/<(\/?)del(\s|>|\/)/ig, "<$1strike$2"); 
     
    44444439    html = html.replace(baseRe, '$1'); 
    44454440  } 
    4446  
    4447 //  if ( Xinha.is_ie ) 
    4448 //  { 
    4449     // This is now done in inward & outward 
    4450     // Don't know why but IE is doing this (putting http://null/ on links?! 
    4451     // alert(html); 
    4452     // var nullRE = new RegExp('https?:\/\/null\/', 'g'); 
    4453     // html = html.replace(nullRE, location.href.replace(/(https?:\/\/[^\/]*\/).*/, '$1')); 
    4454     // alert(html); 
    4455 //  } 
    44564441 
    44574442  return html; 
     
    50625047  { 
    50635048   if ( !this.borders ) 
    5064    { 
    5065     name = "bordered"; 
     5049   {     
    50665050    this.borders = true; 
    50675051   } 
    50685052   else 
    50695053   { 
    5070      name = ""; 
    50715054     this.borders = false; 
    50725055   } 
     
    50765059     if ( this.borders ) 
    50775060     { 
    5078         // flashing the display forces moz to listen (JB:18-04-2005) - #102 
    5079         if ( Xinha.is_gecko ) 
    5080         { 
    5081           tables[i].style.display="none"; 
    5082           tables[i].style.display="table"; 
    5083         } 
    50845061        Xinha._addClass(tables[i], 'htmtableborders'); 
    50855062     } 
     
    51825159{ 
    51835160  var req = null; 
    5184   if ( Xinha.is_ie ) 
    5185   { 
    5186    req = new ActiveXObject("Microsoft.XMLHTTP"); 
    5187   } 
    5188   else 
    5189   { 
    5190    req = new XMLHttpRequest(); 
    5191   } 
     5161  req = Xinha.getXMLHTTPRequestObject(); 
    51925162 
    51935163  var content = ''; 
     
    52335203{ 
    52345204  var req = null; 
    5235   if ( Xinha.is_ie ) 
    5236   { 
    5237    req = new ActiveXObject("Microsoft.XMLHTTP"); 
    5238   } 
    5239   else 
    5240   { 
    5241    req = new XMLHttpRequest(); 
    5242   } 
     5205  req = Xinha.getXMLHTTPRequestObject(); 
    52435206 
    52445207  function callBack() 
     
    52655228{ 
    52665229  var req = null; 
    5267   if ( Xinha.is_ie ) 
    5268   { 
    5269    req = new ActiveXObject("Microsoft.XMLHTTP"); 
    5270   } 
    5271   else 
    5272   { 
    5273    req = new XMLHttpRequest(); 
    5274   } 
     5230  req = Xinha.getXMLHTTPRequestObject(); 
    52755231 
    52765232  // Synchronous! 
     
    55205476/** 
    55215477 * Load a javascript file by inserting it in the HEAD tag and eventually call a function when loaded 
     5478 * 
     5479 * Note that this method cannot be abstracted into browser specific files 
     5480 *  because this method LOADS the browser specific files.  Hopefully it should work for most 
     5481 *  browsers as it is. 
     5482 * 
    55225483 * @param {string} U (Url)      Source url of the file to load 
    55235484 * @param {object} C {Callback} Callback function to launch once ready (optional) 
     
    55255486 * @param {object} B (Bonus}    Arbitrary object send as a param to the callback function (optional) 
    55265487 * @public 
     5488 *  
    55275489 */ 
    5528 Xinha._loadback = function(U, C, O, B) 
    5529 { 
    5530   var T = Xinha.is_ie ? "onreadystatechange" : "onload"; 
     5490  
     5491Xinha._loadback = function(Url, Callback, Scope, Bonus) 
     5492 
     5493  var T = !Xinha.is_ie ? "onload" : 'onreadystatechange'; 
    55315494  var S = document.createElement("script"); 
    55325495  S.type = "text/javascript"; 
    5533   S.src = U; 
    5534   if ( C ) 
     5496  S.src = Url; 
     5497  if ( Callback ) 
    55355498  { 
    55365499    S[T] = function() 
    5537     { 
    5538       if ( Xinha.is_ie && ! ( /loaded|complete/.test(window.event.srcElement.readyState) ) ) 
     5500    {       
     5501      if ( Xinha.is_ie && ( ! ( /loaded|complete/.test(window.event.srcElement.readyState) ) ) ) 
    55395502      { 
    55405503        return; 
    55415504      } 
    5542       C.call(O ? O : this, B); 
     5505       
     5506      Callback.call(Scope ? Scope : this, Bonus); 
    55435507      S[T] = null; 
    55445508    }; 
     
    57385702}; 
    57395703 
     5704/**  
     5705 *  Calculate the top and left pixel position of an element in the DOM. 
     5706 * 
     5707 *  @param   element HTML Element DOM Node 
     5708 *  @returns Object with integer properties top and left 
     5709 */ 
     5710  
     5711Xinha.getElementTopLeft = function(element) 
     5712{ 
     5713  var position = { top:0, left:0 }; 
     5714  while ( element ) 
     5715  { 
     5716    position.top  += element.offsetTop; 
     5717    position.left += element.offsetLeft; 
     5718    if ( element.offsetParent && element.offsetParent.tagName.toLowerCase() != 'body' ) 
     5719    { 
     5720      element = element.offsetParent; 
     5721    } 
     5722    else 
     5723    { 
     5724      element = null; 
     5725    } 
     5726  } 
     5727   
     5728  return position; 
     5729} 
     5730 
    57405731// find X position of an element 
    57415732Xinha.findPosX = function(obj) 
     
    57445735  if ( obj.offsetParent ) 
    57455736  { 
    5746     while ( obj.offsetParent ) 
    5747     { 
    5748       curleft += obj.offsetLeft; 
    5749       obj = obj.offsetParent; 
    5750     } 
     5737    return Xinha.getElementTopLeft(obj).left;     
    57515738  } 
    57525739  else if ( obj.x ) 
     
    57635750  if ( obj.offsetParent ) 
    57645751  { 
    5765     while ( obj.offsetParent ) 
    5766     { 
    5767       curtop += obj.offsetTop; 
    5768       obj = obj.offsetParent; 
    5769     } 
     5752    return Xinha.getElementTopLeft(obj).top;     
    57705753  } 
    57715754  else if ( obj.y ) 
     
    59185901Xinha.prototype.isKeyEvent            = function(event) { Xinha.notImplemented("isKeyEvent"); } 
    59195902 
     5903/** Determines if the given key event object represents a combination of CTRL-<key>, 
     5904 *  which for Xinha is a shortcut.  Note that CTRL-ALT-<key> is not a shortcut. 
     5905 * 
     5906 *  @param    keyEvent 
     5907 *  @returns  true|false 
     5908 */ 
     5909  
     5910Xinha.prototype.isShortCut = function(keyEvent) 
     5911{ 
     5912  if(keyEvent.ctrlKey && !keyEvent.altKey) 
     5913  { 
     5914    return true; 
     5915  } 
     5916   
     5917  return false; 
     5918} 
     5919 
     5920/** Return the character (as a string) of a keyEvent  - ie, press the 'a' key and 
     5921 *  this method will return 'a', press SHIFT-a and it will return 'A'. 
     5922 *  
     5923 *  @param   keyEvent 
     5924 *  @returns string 
     5925 */ 
     5926                                    
     5927Xinha.prototype.getKey = function(keyEvent) { Xinha.notImplemented("getKey"); } 
     5928 
    59205929/** Return the HTML string of the given Element, including the Element. 
    59215930 *  
     
    59265935Xinha.getOuterHTML = function(element) { Xinha.notImplemented("getOuterHTML"); } 
    59275936 
    5928  
    5929  
     5937/** Get a new XMLHTTPRequest Object ready to be used.  
     5938 * 
     5939 * @returns object XMLHTTPRequest  
     5940 */ 
     5941 
     5942Xinha.getXMLHTTPRequestObject = function()  
     5943{        
     5944  try 
     5945  {     
     5946    return new XMLHttpRequest(); 
     5947  } 
     5948  catch(e) 
     5949  { 
     5950    Xinha.notImplemented('getXMLHTTPRequestObject'); 
     5951  } 
     5952} 
     5953  
    59305954// Compatability - all these names are deprecated and will be removed in a future version 
    59315955Xinha.prototype._activeElement  = function(sel) { return this.activeElement(sel); } 
  • trunk/functionsIE.js

    r672 r674  
    5151InternetExplorer.prototype.onKeyPress = function(ev) 
    5252{ 
     53  // Shortcuts 
     54  if(this.editor.isShortCut(ev)) 
     55  { 
     56    switch(this.editor.getKey(ev).toLowerCase()) 
     57    { 
     58      case 'n': 
     59      { 
     60        this.editor.execCommand('formatblock', false, '<p>');         
     61        Xinha._stopEvent(ev); 
     62        return true; 
     63      } 
     64      break; 
     65       
     66      case '1': 
     67      case '2': 
     68      case '3': 
     69      case '4': 
     70      case '5': 
     71      case '6': 
     72      { 
     73        this.editor.execCommand('formatblock', false, '<h'+this.editor.getKey(ev).toLowerCase()+'>'); 
     74        Xinha._stopEvent(ev); 
     75        return true; 
     76      } 
     77      break; 
     78    } 
     79  } 
     80   
    5381  switch(ev.keyCode)  
    5482  { 
     
    107135  } 
    108136}; 
     137 
     138InternetExplorer.prototype.inwardHtml = function(html) 
     139{ 
     140   // Both IE and Gecko use strike internally instead of del (#523) 
     141   // Xinha will present del externally (see Xinha.prototype.outwardHtml 
     142   html = html.replace(/<(\/?)del(\s|>|\/)/ig, "<$1strike$2"); 
     143    
     144   return html; 
     145} 
    109146 
    110147/*--------------------------------------------------------------------------*/ 
     
    338375} 
    339376 
     377/** Return the character (as a string) of a keyEvent  - ie, press the 'a' key and 
     378 *  this method will return 'a', press SHIFT-a and it will return 'A'. 
     379 *  
     380 *  @param   keyEvent 
     381 *  @returns string 
     382 */ 
     383                                    
     384Xinha.prototype.getKey = function(keyEvent) 
     385{ 
     386  return String.fromCharCode(keyEvent.keyCode); 
     387} 
     388 
     389 
    340390/** Return the HTML string of the given Element, including the Element. 
    341391 *  
     
    349399}; 
    350400   
     401/** Get a new XMLHTTPRequest Object ready to be used.  
     402 * 
     403 * @returns object XMLHTTPRequest  
     404 */ 
     405 
     406Xinha.getXMLHTTPRequestObject = function () { return new ActiveXObject("Microsoft.XMLHTTP"); } 
  • trunk/functionsMozilla.js

    r673 r674  
    5252{ 
    5353  var editor = this.editor; 
    54    
    55   if ( ev.ctrlKey &&  editor._unLink && editor._unlinkOnUndo ) 
    56   { 
    57     if ( String.fromCharCode(ev.charCode).toLowerCase() == 'z' ) 
    58     { 
    59       Xinha._stopEvent(ev); 
    60       editor._unLink(); 
    61       editor.updateToolbar(); 
    62       return true; // Stop further 
    63     } 
    64   } 
    65    
    6654  var s = editor._getSelection(); 
    67   var autoWrap = function (textNode, tag) 
    68   { 
    69     var rightText = textNode.nextSibling; 
    70     if ( typeof tag == 'string') 
    71     { 
    72       tag = editor._doc.createElement(tag); 
    73     } 
    74     var a = textNode.parentNode.insertBefore(tag, rightText); 
    75     Xinha.removeFromParent(textNode); 
    76     a.appendChild(textNode); 
    77     rightText.data = ' ' + rightText.data; 
    78  
    79     s.collapse(rightText, 1); 
    80     // Xinha._stopEvent(ev); 
    81  
    82     editor._unLink = function() 
    83     { 
    84       var t = a.firstChild; 
    85       a.removeChild(t); 
    86       a.parentNode.insertBefore(t, a); 
    87       Xinha.removeFromParent(a); 
    88       editor._unLink = null; 
    89       editor._unlinkOnUndo = false; 
    90     }; 
    91     editor._unlinkOnUndo = true; 
    92  
    93     return a; 
    94   }; 
    95  
    96   switch ( ev.which ) 
     55   
     56  // Handle shortcuts 
     57  if(editor.isShortCut(ev)) 
     58  { 
     59    switch(editor.getKey(ev).toLowerCase()) 
     60    { 
     61      case 'z': 
     62      { 
     63        if(editor._unLink && editor._unlinkOnUndo) 
     64        { 
     65          Xinha._stopEvent(ev); 
     66          editor._unLink(); 
     67          editor.updateToolbar(); 
     68          return true; 
     69        } 
     70      } 
     71      break; 
     72       
     73      case 'a': 
     74      { 
     75        // KEY select all 
     76        sel = this._getSelection(); 
     77        sel.removeAllRanges(); 
     78        range = this._createRange(); 
     79        range.selectNodeContents(this._doc.body); 
     80        sel.addRange(range); 
     81        Xinha._stopEvent(ev); 
     82        return true; 
     83      } 
     84      break; 
     85       
     86      case 'v': 
     87      { 
     88        // If we are not using htmlareaPaste, don't let Xinha try and be fancy but let the  
     89        // event be handled normally by the browser (don't stopEvent it) 
     90        if(!editor.config.htmlareaPaste) 
     91        {           
     92          return true; 
     93        } 
     94      } 
     95      break; 
     96    } 
     97  } 
     98   
     99  // Handle normal characters 
     100  switch(editor.getKey(ev)) 
    97101  { 
    98102    // Space, see if the text just typed looks like a URL, or email address 
    99103    // and link it appropriatly 
    100     case 32: 
     104    case ' ': 
     105    {       
     106      var autoWrap = function (textNode, tag) 
     107      { 
     108        var rightText = textNode.nextSibling; 
     109        if ( typeof tag == 'string') 
     110        { 
     111          tag = editor._doc.createElement(tag); 
     112        } 
     113        var a = textNode.parentNode.insertBefore(tag, rightText); 
     114        Xinha.removeFromParent(textNode); 
     115        a.appendChild(textNode); 
     116        rightText.data = ' ' + rightText.data; 
     117     
     118        s.collapse(rightText, 1); 
     119     
     120        editor._unLink = function() 
     121        { 
     122          var t = a.firstChild; 
     123          a.removeChild(t); 
     124          a.parentNode.insertBefore(t, a); 
     125          Xinha.removeFromParent(a); 
     126          editor._unLink = null; 
     127          editor._unlinkOnUndo = false; 
     128        }; 
     129        editor._unlinkOnUndo = true; 
     130     
     131        return a; 
     132      }; 
     133   
    101134      if ( editor.config.convertUrlsToLinks && s && s.isCollapsed && s.anchorNode.nodeType == 3 && s.anchorNode.data.length > 3 && s.anchorNode.data.indexOf('.') >= 0 ) 
    102135      { 
     
    144177        } 
    145178      } 
     179    } 
     180    break;     
     181  } 
     182   
     183  // Handle special keys 
     184  switch ( ev.keyCode ) 
     185  {     
     186    case 13: // ENTER 
     187      if( !ev.shiftKey && editor.config.mozParaHandler == 'dirty' ) 
     188      { 
     189        editor.dom_checkInsertP(); 
     190        Xinha._stopEvent(ev); 
     191      } 
    146192    break; 
    147193 
     194    case 27: // ESCAPE 
     195    { 
     196      if ( editor._unLink ) 
     197      { 
     198        editor._unLink(); 
     199        Xinha._stopEvent(ev); 
     200      } 
     201      break; 
     202    } 
     203    break; 
     204     
     205    case 8: // KEY backspace 
     206    case 46: // KEY delete 
     207    { 
     208      // We handle the mozilla backspace directly?? 
     209      if ( !ev.shiftKey && this.handleBackspace() ) 
     210      { 
     211        Xinha._stopEvent(ev); 
     212      } 
     213    } 
     214     
    148215    default: 
    149       if ( ev.keyCode == 27 || ( editor._unlinkOnUndo && ev.ctrlKey && ev.which == 122 ) ) 
    150       { 
    151         if ( editor._unLink ) 
    152         { 
    153           editor._unLink(); 
    154           Xinha._stopEvent(ev); 
    155         } 
    156         break; 
    157       } 
    158       else if ( ev.which || ev.keyCode == 8 || ev.keyCode == 46 ) 
    159       { 
     216    { 
    160217        editor._unlinkOnUndo = false; 
    161218 
     219        // Handle the "auto-linking", specifically this bit of code sets up a handler on 
     220        // an self-titled anchor (eg <a href="http://www.gogo.co.nz/">www.gogo.co.nz</a>) 
     221        // when the text content is edited, such that it will update the href on the anchor 
     222         
    162223        if ( s.anchorNode && s.anchorNode.nodeType == 3 ) 
    163224        { 
     
    169230            break; // not an anchor 
    170231          }  
     232           
    171233          if ( !a._updateAnchTimeout ) 
    172234          { 
     
    180242                //         This lead to never ending timer if we dont remove this line 
    181243                //         But when removed, the email is not correctly updated 
     244                // 
     245                // - to fix this we should make fnAnchor check to see if textNode.data has 
     246                //   stopped changing for say 5 seconds and if so we do not make this setTimeout  
    182247                a._updateAnchTimeout = setTimeout(fnAnchor, 250); 
    183248              }; 
     
    192257              var fnUrl = function() 
    193258              { 
    194                 // @fixme: Alert, sometimes m is undefined becase the url is not an url anymore (was www.url.com and become for example www.url) 
     259                // Sometimes m is undefined becase the url is not an url anymore (was www.url.com and become for example www.url) 
    195260                m = txtNode.data.match(Xinha.RE_url); 
    196                 a.href = (m[1] ? m[1] : 'http://') + m[2]; 
     261                if(m) 
     262                { 
     263                  a.href = (m[1] ? m[1] : 'http://') + m[2]; 
     264                } 
     265                 
    197266                // @fixme: why the hell do another timeout is started ? 
    198267                //         This lead to never ending timer if we dont remove this line 
    199268                //         But when removed, the url is not correctly updated 
     269                // 
     270                // - to fix this we should make fnUrl check to see if textNode.data has 
     271                //   stopped changing for say 5 seconds and if so we do not make this setTimeout 
    200272                a._updateAnchTimeout = setTimeout(fnUrl, 250); 
    201273              }; 
    202274              a._updateAnchTimeout = setTimeout(fnUrl, 1000); 
    203275            } 
    204           } 
    205         } 
    206       } 
     276          }         
     277        }                 
     278    } 
    207279    break; 
    208280  } 
    209281 
    210   // other keys here 
    211   switch (ev.keyCode) 
    212   { 
    213     case 13: // KEY enter 
    214       if( !ev.shiftKey && editor.config.mozParaHandler == 'dirty' ) 
    215       { 
    216         editor.dom_checkInsertP(); 
    217         Xinha._stopEvent(ev); 
    218       } 
    219     break; 
    220     case 8: // KEY backspace 
    221     case 46: // KEY delete 
    222       if ( !ev.shiftKey && this.handleBackspace() ) 
    223       { 
    224         Xinha._stopEvent(ev); 
    225       } 
    226     break; 
    227   } 
    228    
    229282  return false; // Let other plugins etc continue from here. 
    230283} 
     
    270323    10); 
    271324}; 
     325 
     326Gecko.prototype.inwardHtml = function(html) 
     327{ 
     328   // Midas uses b and i internally instead of strong and em 
     329   // Xinha will use strong and em externally (see Xinha.prototype.outwardHtml)    
     330   html = html.replace(/<(\/?)strong(\s|>|\/)/ig, "<$1b$2"); 
     331   html = html.replace(/<(\/?)em(\s|>|\/)/ig, "<$1i$2");     
     332    
     333   // Both IE and Gecko use strike internally instead of del (#523) 
     334   // Xinha will present del externally (see Xinha.prototype.outwardHtml 
     335   html = html.replace(/<(\/?)del(\s|>|\/)/ig, "<$1strike$2"); 
     336    
     337   return html; 
     338} 
     339 
     340Gecko.prototype.outwardHtml = function(html) 
     341{ 
     342  // ticket:56, the "greesemonkey" plugin for Firefox adds this junk, 
     343  // so we strip it out.  Original submitter gave a plugin, but that's 
     344  // a bit much just for this IMHO - james 
     345  html = html.replace(/<script[\s]*src[\s]*=[\s]*['"]chrome:\/\/.*?["']>[\s]*<\/script>/ig, ''); 
     346 
     347  return html; 
     348} 
     349 
     350Gecko.prototype.onExecCommand = function(cmdID, UI, param) 
     351{    
     352  try 
     353  { 
     354    // useCSS deprecated & replaced by styleWithCSS 
     355    this.editor._doc.execCommand('useCSS', false, true); //switch useCSS off (true=off) 
     356    this.editor._doc.execCommand('styleWithCSS', false, false); //switch styleWithCSS off      
     357  } catch (ex) {} 
     358     
     359  switch(cmdID) 
     360  { 
     361    case 'paste': 
     362    { 
     363      alert(Xinha._lc("The Paste button does not work in Mozilla based web browsers (technical security reasons). Press CTRL-V on your keyboard to paste directly.")); 
     364      return true; // Indicate paste is done, stop command being issued to browser by Xinha.prototype.execCommand 
     365    } 
     366  } 
     367   
     368  return false; 
     369} 
     370 
    272371 
    273372/*--------------------------------------------------------------------------*/ 
     
    530629} 
    531630 
     631/** Return the character (as a string) of a keyEvent  - ie, press the 'a' key and 
     632 *  this method will return 'a', press SHIFT-a and it will return 'A'. 
     633 *  
     634 *  @param   keyEvent 
     635 *  @returns string 
     636 */ 
     637                                    
     638Xinha.prototype.getKey = function(keyEvent) 
     639{ 
     640  return String.fromCharCode(keyEvent.charCode); 
     641} 
     642 
    532643/** Return the HTML string of the given Element, including the Element. 
    533644 *  
     
    540651  return (new XMLSerializer()).serializeToString(element); 
    541652}; 
     653 
     654/*--------------------------------------------------------------------------*/ 
     655/*------------ EXTEND SOME STANDARD "Xinha.prototype" METHODS --------------*/ 
     656/*--------------------------------------------------------------------------*/ 
     657 
     658Xinha.prototype._standardToggleBorders = Xinha.prototype._toggleBorders; 
     659Xinha.prototype._toggleBorders = function() 
     660{ 
     661  var result = Xinha.prototype._standardToggleBorders(); 
     662   
     663  // flashing the display forces moz to listen (JB:18-04-2005) - #102 
     664  var tables = this._doc.getElementByTagName('TABLE'); 
     665  for(var i = 0; i < tables.length; i++) 
     666  { 
     667    tables[i].style.display="none"; 
     668    tables[i].style.display="table"; 
     669  } 
     670   
     671  return result; 
     672} 
Note: See TracChangeset for help on using the changeset viewer.