[ Index ]

PHP Cross Reference of Drupal 6 (yi-drupal)

title

Body

[close]

/sites/all/modules/fckeditor/fckeditor/editor/_source/classes/ -> fckenterkey.js (source)

   1  /*

   2   * FCKeditor - The text editor for Internet - http://www.fckeditor.net

   3   * Copyright (C) 2003-2009 Frederico Caldeira Knabben

   4   *

   5   * == BEGIN LICENSE ==

   6   *

   7   * Licensed under the terms of any of the following licenses at your

   8   * choice:

   9   *

  10   *  - GNU General Public License Version 2 or later (the "GPL")

  11   *    http://www.gnu.org/licenses/gpl.html

  12   *

  13   *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")

  14   *    http://www.gnu.org/licenses/lgpl.html

  15   *

  16   *  - Mozilla Public License Version 1.1 or later (the "MPL")

  17   *    http://www.mozilla.org/MPL/MPL-1.1.html

  18   *

  19   * == END LICENSE ==

  20   *

  21   * Controls the [Enter] keystroke behavior in a document.

  22   */
  23  
  24  /*

  25   *    Constructor.

  26   *        @targetDocument : the target document.

  27   *        @enterMode : the behavior for the <Enter> keystroke.

  28   *            May be "p", "div", "br". Default is "p".

  29   *        @shiftEnterMode : the behavior for the <Shift>+<Enter> keystroke.

  30   *            May be "p", "div", "br". Defaults to "br".

  31   */
  32  var FCKEnterKey = function( targetWindow, enterMode, shiftEnterMode, tabSpaces )
  33  {
  34      this.Window            = targetWindow ;
  35      this.EnterMode        = enterMode || 'p' ;
  36      this.ShiftEnterMode    = shiftEnterMode || 'br' ;
  37  
  38      // Setup the Keystroke Handler.

  39      var oKeystrokeHandler = new FCKKeystrokeHandler( false ) ;
  40      oKeystrokeHandler._EnterKey = this ;
  41      oKeystrokeHandler.OnKeystroke = FCKEnterKey_OnKeystroke ;
  42  
  43      oKeystrokeHandler.SetKeystrokes( [
  44          [ 13        , 'Enter' ],
  45          [ SHIFT + 13, 'ShiftEnter' ],
  46          [ 8            , 'Backspace' ],
  47          [ CTRL + 8    , 'CtrlBackspace' ],
  48          [ 46        , 'Delete' ]
  49      ] ) ;
  50  
  51      this.TabText = '' ;
  52  
  53      // Safari by default inserts 4 spaces on TAB, while others make the editor

  54      // loose focus. So, we need to handle it here to not include those spaces.

  55      if ( tabSpaces > 0 || FCKBrowserInfo.IsSafari )
  56      {
  57          while ( tabSpaces-- )
  58              this.TabText += '\xa0' ;
  59  
  60          oKeystrokeHandler.SetKeystrokes( [ 9, 'Tab' ] );
  61      }
  62  
  63      oKeystrokeHandler.AttachToElement( targetWindow.document ) ;
  64  }
  65  
  66  
  67  function FCKEnterKey_OnKeystroke(  keyCombination, keystrokeValue )
  68  {
  69      var oEnterKey = this._EnterKey ;
  70  
  71      try
  72      {
  73          switch ( keystrokeValue )
  74          {
  75              case 'Enter' :
  76                  return oEnterKey.DoEnter() ;
  77                  break ;
  78              case 'ShiftEnter' :
  79                  return oEnterKey.DoShiftEnter() ;
  80                  break ;
  81              case 'Backspace' :
  82                  return oEnterKey.DoBackspace() ;
  83                  break ;
  84              case 'Delete' :
  85                  return oEnterKey.DoDelete() ;
  86                  break ;
  87              case 'Tab' :
  88                  return oEnterKey.DoTab() ;
  89                  break ;
  90              case 'CtrlBackspace' :
  91                  return oEnterKey.DoCtrlBackspace() ;
  92                  break ;
  93          }
  94      }
  95      catch (e)
  96      {
  97          // If for any reason we are not able to handle it, go

  98          // ahead with the browser default behavior.

  99      }
 100  
 101      return false ;
 102  }
 103  
 104  /*

 105   * Executes the <Enter> key behavior.

 106   */
 107  FCKEnterKey.prototype.DoEnter = function( mode, hasShift )
 108  {
 109      // Save an undo snapshot before doing anything

 110      FCKUndo.SaveUndoStep() ;
 111  
 112      this._HasShift = ( hasShift === true ) ;
 113  
 114      var parentElement = FCKSelection.GetParentElement() ;
 115      var parentPath = new FCKElementPath( parentElement ) ;
 116      var sMode = mode || this.EnterMode ;
 117  
 118      if ( sMode == 'br' || parentPath.Block && parentPath.Block.tagName.toLowerCase() == 'pre' )
 119          return this._ExecuteEnterBr() ;
 120      else
 121          return this._ExecuteEnterBlock( sMode ) ;
 122  }
 123  
 124  /*

 125   * Executes the <Shift>+<Enter> key behavior.

 126   */
 127  FCKEnterKey.prototype.DoShiftEnter = function()
 128  {
 129      return this.DoEnter( this.ShiftEnterMode, true ) ;
 130  }
 131  
 132  /*

 133   * Executes the <Backspace> key behavior.

 134   */
 135  FCKEnterKey.prototype.DoBackspace = function()
 136  {
 137      var bCustom = false ;
 138  
 139      // Get the current selection.

 140      var oRange = new FCKDomRange( this.Window ) ;
 141      oRange.MoveToSelection() ;
 142  
 143      // Kludge for #247

 144      if ( FCKBrowserInfo.IsIE && this._CheckIsAllContentsIncluded( oRange, this.Window.document.body ) )
 145      {
 146          this._FixIESelectAllBug( oRange ) ;
 147          return true ;
 148      }
 149  
 150      var isCollapsed = oRange.CheckIsCollapsed() ;
 151  
 152      if ( !isCollapsed )
 153      {
 154          // Bug #327, Backspace with an img selection would activate the default action in IE.

 155          // Let's override that with our logic here.

 156          if ( FCKBrowserInfo.IsIE && this.Window.document.selection.type.toLowerCase() == "control" )
 157          {
 158              var controls = this.Window.document.selection.createRange() ;
 159              for ( var i = controls.length - 1 ; i >= 0 ; i-- )
 160              {
 161                  var el = controls.item( i ) ;
 162                  el.parentNode.removeChild( el ) ;
 163              }
 164              return true ;
 165          }
 166  
 167          return false ;
 168      }
 169  
 170      // On IE, it is better for us handle the deletion if the caret is preceeded

 171      // by a <br> (#1383).

 172      if ( FCKBrowserInfo.IsIE )
 173      {
 174          var previousElement = FCKDomTools.GetPreviousSourceElement( oRange.StartNode, true ) ;
 175  
 176          if ( previousElement && previousElement.nodeName.toLowerCase() == 'br' )
 177          {
 178              // Create a range that starts after the <br> and ends at the

 179              // current range position.

 180              var testRange = oRange.Clone() ;
 181              testRange.SetStart( previousElement, 4 ) ;
 182  
 183              // If that range is empty, we can proceed cleaning that <br> manually.

 184              if ( testRange.CheckIsEmpty() )
 185              {
 186                  previousElement.parentNode.removeChild( previousElement ) ;
 187                  return true ;
 188              }
 189          }
 190      }
 191  
 192      var oStartBlock = oRange.StartBlock ;
 193      var oEndBlock = oRange.EndBlock ;
 194  
 195      // The selection boundaries must be in the same "block limit" element

 196      if ( oRange.StartBlockLimit == oRange.EndBlockLimit && oStartBlock && oEndBlock )
 197      {
 198          if ( !isCollapsed )
 199          {
 200              var bEndOfBlock = oRange.CheckEndOfBlock() ;
 201  
 202              oRange.DeleteContents() ;
 203  
 204              if ( oStartBlock != oEndBlock )
 205              {
 206                  oRange.SetStart(oEndBlock,1) ;
 207                  oRange.SetEnd(oEndBlock,1) ;
 208  
 209  //                if ( bEndOfBlock )

 210  //                    oEndBlock.parentNode.removeChild( oEndBlock ) ;

 211              }
 212  
 213              oRange.Select() ;
 214  
 215              bCustom = ( oStartBlock == oEndBlock ) ;
 216          }
 217  
 218          if ( oRange.CheckStartOfBlock() )
 219          {
 220              var oCurrentBlock = oRange.StartBlock ;
 221  
 222              var ePrevious = FCKDomTools.GetPreviousSourceElement( oCurrentBlock, true, [ 'BODY', oRange.StartBlockLimit.nodeName ], ['UL','OL'] ) ;
 223  
 224              bCustom = this._ExecuteBackspace( oRange, ePrevious, oCurrentBlock ) ;
 225          }
 226          else if ( FCKBrowserInfo.IsGeckoLike )
 227          {
 228              // Firefox and Opera (#1095) loose the selection when executing

 229              // CheckStartOfBlock, so we must reselect.

 230              oRange.Select() ;
 231          }
 232      }
 233  
 234      oRange.Release() ;
 235      return bCustom ;
 236  }
 237  
 238  FCKEnterKey.prototype.DoCtrlBackspace = function()
 239  {
 240      FCKUndo.SaveUndoStep() ;
 241      var oRange = new FCKDomRange( this.Window ) ;
 242      oRange.MoveToSelection() ;
 243      if ( FCKBrowserInfo.IsIE && this._CheckIsAllContentsIncluded( oRange, this.Window.document.body ) )
 244      {
 245          this._FixIESelectAllBug( oRange ) ;
 246          return true ;
 247      }
 248      return false ;
 249  }
 250  
 251  FCKEnterKey.prototype._ExecuteBackspace = function( range, previous, currentBlock )
 252  {
 253      var bCustom = false ;
 254  
 255      // We could be in a nested LI.

 256      if ( !previous && currentBlock && currentBlock.nodeName.IEquals( 'LI' ) && currentBlock.parentNode.parentNode.nodeName.IEquals( 'LI' ) )
 257      {
 258          this._OutdentWithSelection( currentBlock, range ) ;
 259          return true ;
 260      }
 261  
 262      if ( previous && previous.nodeName.IEquals( 'LI' ) )
 263      {
 264          var oNestedList = FCKDomTools.GetLastChild( previous, ['UL','OL'] ) ;
 265  
 266          while ( oNestedList )
 267          {
 268              previous = FCKDomTools.GetLastChild( oNestedList, 'LI' ) ;
 269              oNestedList = FCKDomTools.GetLastChild( previous, ['UL','OL'] ) ;
 270          }
 271      }
 272  
 273      if ( previous && currentBlock )
 274      {
 275          // If we are in a LI, and the previous block is not an LI, we must outdent it.

 276          if ( currentBlock.nodeName.IEquals( 'LI' ) && !previous.nodeName.IEquals( 'LI' ) )
 277          {
 278              this._OutdentWithSelection( currentBlock, range ) ;
 279              return true ;
 280          }
 281  
 282          // Take a reference to the parent for post processing cleanup.

 283          var oCurrentParent = currentBlock.parentNode ;
 284  
 285          var sPreviousName = previous.nodeName.toLowerCase() ;
 286          if ( FCKListsLib.EmptyElements[ sPreviousName ] != null || sPreviousName == 'table' )
 287          {
 288              FCKDomTools.RemoveNode( previous ) ;
 289              bCustom = true ;
 290          }
 291          else
 292          {
 293              // Remove the current block.

 294              FCKDomTools.RemoveNode( currentBlock ) ;
 295  
 296              // Remove any empty tag left by the block removal.

 297              while ( oCurrentParent.innerHTML.Trim().length == 0 )
 298              {
 299                  var oParent = oCurrentParent.parentNode ;
 300                  oParent.removeChild( oCurrentParent ) ;
 301                  oCurrentParent = oParent ;
 302              }
 303  
 304              // Cleanup the previous and the current elements.

 305              FCKDomTools.LTrimNode( currentBlock ) ;
 306              FCKDomTools.RTrimNode( previous ) ;
 307  
 308              // Append a space to the previous.

 309              // Maybe it is not always desirable...

 310              // previous.appendChild( this.Window.document.createTextNode( ' ' ) ) ;

 311  
 312              // Set the range to the end of the previous element and bookmark it.

 313              range.SetStart( previous, 2, true ) ;
 314              range.Collapse( true ) ;
 315              var oBookmark = range.CreateBookmark( true ) ;
 316  
 317              // Move the contents of the block to the previous element and delete it.

 318              // But for some block types (e.g. table), moving the children to the previous block makes no sense.

 319              // So a check is needed. (See #1081)

 320              if ( ! currentBlock.tagName.IEquals( [ 'TABLE' ] ) )
 321                  FCKDomTools.MoveChildren( currentBlock, previous ) ;
 322  
 323              // Place the selection at the bookmark.

 324              range.SelectBookmark( oBookmark ) ;
 325  
 326              bCustom = true ;
 327          }
 328      }
 329  
 330      return bCustom ;
 331  }
 332  
 333  /*

 334   * Executes the <Delete> key behavior.

 335   */
 336  FCKEnterKey.prototype.DoDelete = function()
 337  {
 338      // Save an undo snapshot before doing anything

 339      // This is to conform with the behavior seen in MS Word

 340      FCKUndo.SaveUndoStep() ;
 341  
 342      // The <Delete> has the same effect as the <Backspace>, so we have the same

 343      // results if we just move to the next block and apply the same <Backspace> logic.

 344  
 345      var bCustom = false ;
 346  
 347      // Get the current selection.

 348      var oRange = new FCKDomRange( this.Window ) ;
 349      oRange.MoveToSelection() ;
 350  
 351      // Kludge for #247

 352      if ( FCKBrowserInfo.IsIE && this._CheckIsAllContentsIncluded( oRange, this.Window.document.body ) )
 353      {
 354          this._FixIESelectAllBug( oRange ) ;
 355          return true ;
 356      }
 357  
 358      // There is just one special case for collapsed selections at the end of a block.

 359      if ( oRange.CheckIsCollapsed() && oRange.CheckEndOfBlock( FCKBrowserInfo.IsGeckoLike ) )
 360      {
 361          var oCurrentBlock = oRange.StartBlock ;
 362          var eCurrentCell = FCKTools.GetElementAscensor( oCurrentBlock, 'td' );
 363  
 364          var eNext = FCKDomTools.GetNextSourceElement( oCurrentBlock, true, [ oRange.StartBlockLimit.nodeName ],
 365                  ['UL','OL','TR'], true ) ;
 366  
 367          // Bug #1323 : if we're in a table cell, and the next node belongs to a different cell, then don't

 368          // delete anything.

 369          if ( eCurrentCell )
 370          {
 371              var eNextCell = FCKTools.GetElementAscensor( eNext, 'td' );
 372              if ( eNextCell != eCurrentCell )
 373                  return true ;
 374          }
 375  
 376          bCustom = this._ExecuteBackspace( oRange, oCurrentBlock, eNext ) ;
 377      }
 378  
 379      oRange.Release() ;
 380      return bCustom ;
 381  }
 382  
 383  /*

 384   * Executes the <Tab> key behavior.

 385   */
 386  FCKEnterKey.prototype.DoTab = function()
 387  {
 388      var oRange = new FCKDomRange( this.Window );
 389      oRange.MoveToSelection() ;
 390  
 391      // If the user pressed <tab> inside a table, we should give him the default behavior ( moving between cells )

 392      // instead of giving him more non-breaking spaces. (Bug #973)

 393      var node = oRange._Range.startContainer ;
 394      while ( node )
 395      {
 396          if ( node.nodeType == 1 )
 397          {
 398              var tagName = node.tagName.toLowerCase() ;
 399              if ( tagName == "tr" || tagName == "td" || tagName == "th" || tagName == "tbody" || tagName == "table" )
 400                  return false ;
 401              else
 402                  break ;
 403          }
 404          node = node.parentNode ;
 405      }
 406  
 407      if ( this.TabText )
 408      {
 409          oRange.DeleteContents() ;
 410          oRange.InsertNode( this.Window.document.createTextNode( this.TabText ) ) ;
 411          oRange.Collapse( false ) ;
 412          oRange.Select() ;
 413      }
 414      return true ;
 415  }
 416  
 417  FCKEnterKey.prototype._ExecuteEnterBlock = function( blockTag, range )
 418  {
 419      // Get the current selection.

 420      var oRange = range || new FCKDomRange( this.Window ) ;
 421  
 422      var oSplitInfo = oRange.SplitBlock( blockTag ) ;
 423  
 424      if ( oSplitInfo )
 425      {
 426          // Get the current blocks.

 427          var ePreviousBlock    = oSplitInfo.PreviousBlock ;
 428          var eNextBlock        = oSplitInfo.NextBlock ;
 429  
 430          var bIsStartOfBlock    = oSplitInfo.WasStartOfBlock ;
 431          var bIsEndOfBlock    = oSplitInfo.WasEndOfBlock ;
 432  
 433          // If there is one block under a list item, modify the split so that the list item gets split as well. (Bug #1647)

 434          if ( eNextBlock )
 435          {
 436              if ( eNextBlock.parentNode.nodeName.IEquals( 'li' ) )
 437              {
 438                  FCKDomTools.BreakParent( eNextBlock, eNextBlock.parentNode ) ;
 439                  FCKDomTools.MoveNode( eNextBlock, eNextBlock.nextSibling, true ) ;
 440              }
 441          }
 442          else if ( ePreviousBlock && ePreviousBlock.parentNode.nodeName.IEquals( 'li' ) )
 443          {
 444              FCKDomTools.BreakParent( ePreviousBlock, ePreviousBlock.parentNode ) ;
 445              oRange.MoveToElementEditStart( ePreviousBlock.nextSibling );
 446              FCKDomTools.MoveNode( ePreviousBlock, ePreviousBlock.previousSibling ) ;
 447          }
 448  
 449          // If we have both the previous and next blocks, it means that the

 450          // boundaries were on separated blocks, or none of them where on the

 451          // block limits (start/end).

 452          if ( !bIsStartOfBlock && !bIsEndOfBlock )
 453          {
 454              // If the next block is an <li> with another list tree as the first child

 455              // We'll need to append a placeholder or the list item wouldn't be editable. (Bug #1420)

 456              if ( eNextBlock.nodeName.IEquals( 'li' ) && eNextBlock.firstChild
 457                      && eNextBlock.firstChild.nodeName.IEquals( ['ul', 'ol'] ) )
 458                  eNextBlock.insertBefore( FCKTools.GetElementDocument( eNextBlock ).createTextNode( '\xa0' ), eNextBlock.firstChild ) ;
 459              // Move the selection to the end block.

 460              if ( eNextBlock )
 461                  oRange.MoveToElementEditStart( eNextBlock ) ;
 462          }
 463          else
 464          {
 465              if ( bIsStartOfBlock && bIsEndOfBlock && ePreviousBlock.tagName.toUpperCase() == 'LI' )
 466              {
 467                  oRange.MoveToElementStart( ePreviousBlock ) ;
 468                  this._OutdentWithSelection( ePreviousBlock, oRange ) ;
 469                  oRange.Release() ;
 470                  return true ;
 471              }
 472  
 473              var eNewBlock ;
 474  
 475              if ( ePreviousBlock )
 476              {
 477                  var sPreviousBlockTag = ePreviousBlock.tagName.toUpperCase() ;
 478  
 479                  // If is a header tag, or we are in a Shift+Enter (#77),

 480                  // create a new block element (later in the code).

 481                  if ( !this._HasShift && !(/^H[1-6]$/).test( sPreviousBlockTag ) )
 482                  {
 483                      // Otherwise, duplicate the previous block.

 484                      eNewBlock = FCKDomTools.CloneElement( ePreviousBlock ) ;
 485                  }
 486              }
 487              else if ( eNextBlock )
 488                  eNewBlock = FCKDomTools.CloneElement( eNextBlock ) ;
 489  
 490              if ( !eNewBlock )
 491                  eNewBlock = this.Window.document.createElement( blockTag ) ;
 492  
 493              // Recreate the inline elements tree, which was available

 494              // before the hitting enter, so the same styles will be

 495              // available in the new block.

 496              var elementPath = oSplitInfo.ElementPath ;
 497              if ( elementPath )
 498              {
 499                  for ( var i = 0, len = elementPath.Elements.length ; i < len ; i++ )
 500                  {
 501                      var element = elementPath.Elements[i] ;
 502  
 503                      if ( element == elementPath.Block || element == elementPath.BlockLimit )
 504                          break ;
 505  
 506                      if ( FCKListsLib.InlineChildReqElements[ element.nodeName.toLowerCase() ] )
 507                      {
 508                          element = FCKDomTools.CloneElement( element ) ;
 509                          FCKDomTools.MoveChildren( eNewBlock, element ) ;
 510                          eNewBlock.appendChild( element ) ;
 511                      }
 512                  }
 513              }
 514  
 515              if ( FCKBrowserInfo.IsGeckoLike )
 516                  FCKTools.AppendBogusBr( eNewBlock ) ;
 517  
 518              oRange.InsertNode( eNewBlock ) ;
 519  
 520              // This is tricky, but to make the new block visible correctly

 521              // we must select it.

 522              if ( FCKBrowserInfo.IsIE )
 523              {
 524                  // Move the selection to the new block.

 525                  oRange.MoveToElementEditStart( eNewBlock ) ;
 526                  oRange.Select() ;
 527              }
 528  
 529              // Move the selection to the new block.

 530              oRange.MoveToElementEditStart( bIsStartOfBlock && !bIsEndOfBlock ? eNextBlock : eNewBlock ) ;
 531          }
 532  
 533          if ( FCKBrowserInfo.IsGeckoLike )
 534          {
 535              if ( eNextBlock )
 536              {
 537                  // If we have split the block, adds a temporary span at the

 538                  // range position and scroll relatively to it.

 539                  var tmpNode = this.Window.document.createElement( 'span' ) ;
 540  
 541                  // We need some content for Safari.

 542                  tmpNode.innerHTML = '&nbsp;';
 543  
 544                  oRange.InsertNode( tmpNode ) ;
 545                  FCKDomTools.ScrollIntoView( tmpNode, false ) ;
 546                  oRange.DeleteContents() ;
 547              }
 548              else
 549              {
 550                  // We may use the above scroll logic for the new block case

 551                  // too, but it gives some weird result with Opera.

 552                  FCKDomTools.ScrollIntoView( eNextBlock || eNewBlock, false ) ;
 553              }
 554          }
 555  
 556          oRange.Select() ;
 557      }
 558  
 559      // Release the resources used by the range.

 560      oRange.Release() ;
 561  
 562      return true ;
 563  }
 564  
 565  FCKEnterKey.prototype._ExecuteEnterBr = function( blockTag )
 566  {
 567      // Get the current selection.

 568      var oRange = new FCKDomRange( this.Window ) ;
 569      oRange.MoveToSelection() ;
 570  
 571      // The selection boundaries must be in the same "block limit" element.

 572      if ( oRange.StartBlockLimit == oRange.EndBlockLimit )
 573      {
 574          oRange.DeleteContents() ;
 575  
 576          // Get the new selection (it is collapsed at this point).

 577          oRange.MoveToSelection() ;
 578  
 579          var bIsStartOfBlock    = oRange.CheckStartOfBlock() ;
 580          var bIsEndOfBlock    = oRange.CheckEndOfBlock() ;
 581  
 582          var sStartBlockTag = oRange.StartBlock ? oRange.StartBlock.tagName.toUpperCase() : '' ;
 583  
 584          var bHasShift = this._HasShift ;
 585          var bIsPre = false ;
 586  
 587          if ( !bHasShift && sStartBlockTag == 'LI' )
 588              return this._ExecuteEnterBlock( null, oRange ) ;
 589  
 590          // If we are at the end of a header block.

 591          if ( !bHasShift && bIsEndOfBlock && (/^H[1-6]$/).test( sStartBlockTag ) )
 592          {
 593              // Insert a BR after the current paragraph.

 594              FCKDomTools.InsertAfterNode( oRange.StartBlock, this.Window.document.createElement( 'br' ) ) ;
 595  
 596              // The space is required by Gecko only to make the cursor blink.

 597              if ( FCKBrowserInfo.IsGecko )
 598                  FCKDomTools.InsertAfterNode( oRange.StartBlock, this.Window.document.createTextNode( '' ) ) ;
 599  
 600              // IE and Gecko have different behaviors regarding the position.

 601              oRange.SetStart( oRange.StartBlock.nextSibling, FCKBrowserInfo.IsIE ? 3 : 1 ) ;
 602          }
 603          else
 604          {
 605              var eLineBreak ;
 606              bIsPre = sStartBlockTag.IEquals( 'pre' ) ;
 607              if ( bIsPre )
 608                  eLineBreak = this.Window.document.createTextNode( FCKBrowserInfo.IsIE ? '\r' : '\n' ) ;
 609              else
 610                  eLineBreak = this.Window.document.createElement( 'br' ) ;
 611  
 612              oRange.InsertNode( eLineBreak ) ;
 613  
 614              // The space is required by Gecko only to make the cursor blink.

 615              if ( FCKBrowserInfo.IsGecko )
 616                  FCKDomTools.InsertAfterNode( eLineBreak, this.Window.document.createTextNode( '' ) ) ;
 617  
 618              // If we are at the end of a block, we must be sure the bogus node is available in that block.

 619              if ( bIsEndOfBlock && FCKBrowserInfo.IsGeckoLike )
 620                  FCKTools.AppendBogusBr( eLineBreak.parentNode ) ;
 621  
 622              if ( FCKBrowserInfo.IsIE )
 623                  oRange.SetStart( eLineBreak, 4 ) ;
 624              else
 625                  oRange.SetStart( eLineBreak.nextSibling, 1 ) ;
 626  
 627              if ( ! FCKBrowserInfo.IsIE )
 628              {
 629                  var dummy = null ;
 630                  if ( FCKBrowserInfo.IsOpera )
 631                      dummy = this.Window.document.createElement( 'span' ) ;
 632                  else
 633                      dummy = this.Window.document.createElement( 'br' ) ;
 634  
 635                  eLineBreak.parentNode.insertBefore( dummy, eLineBreak.nextSibling ) ;
 636  
 637                  FCKDomTools.ScrollIntoView( dummy, false ) ;
 638  
 639                  dummy.parentNode.removeChild( dummy ) ;
 640              }
 641          }
 642  
 643          // This collapse guarantees the cursor will be blinking.

 644          oRange.Collapse( true ) ;
 645  
 646          oRange.Select( bIsPre ) ;
 647      }
 648  
 649      // Release the resources used by the range.

 650      oRange.Release() ;
 651  
 652      return true ;
 653  }
 654  
 655  // Outdents a LI, maintaining the selection defined on a range.

 656  FCKEnterKey.prototype._OutdentWithSelection = function( li, range )
 657  {
 658      var oBookmark = range.CreateBookmark() ;
 659  
 660      FCKListHandler.OutdentListItem( li ) ;
 661  
 662      range.MoveToBookmark( oBookmark ) ;
 663      range.Select() ;
 664  }
 665  
 666  // Is all the contents under a node included by a range?

 667  FCKEnterKey.prototype._CheckIsAllContentsIncluded = function( range, node )
 668  {
 669      var startOk = false ;
 670      var endOk = false ;
 671  
 672      /*

 673      FCKDebug.Output( 'sc='+range.StartContainer.nodeName+

 674              ',so='+range._Range.startOffset+

 675              ',ec='+range.EndContainer.nodeName+

 676              ',eo='+range._Range.endOffset ) ;

 677      */
 678      if ( range.StartContainer == node || range.StartContainer == node.firstChild )
 679          startOk = ( range._Range.startOffset == 0 ) ;
 680  
 681      if ( range.EndContainer == node || range.EndContainer == node.lastChild )
 682      {
 683          var nodeLength = range.EndContainer.nodeType == 3 ? range.EndContainer.length : range.EndContainer.childNodes.length ;
 684          endOk = ( range._Range.endOffset == nodeLength ) ;
 685      }
 686  
 687      return startOk && endOk ;
 688  }
 689  
 690  // Kludge for #247

 691  FCKEnterKey.prototype._FixIESelectAllBug = function( range )
 692  {
 693      var doc = this.Window.document ;
 694      doc.body.innerHTML = '' ;
 695      var editBlock ;
 696      if ( FCKConfig.EnterMode.IEquals( ['div', 'p'] ) )
 697      {
 698          editBlock = doc.createElement( FCKConfig.EnterMode ) ;
 699          doc.body.appendChild( editBlock ) ;
 700      }
 701      else
 702          editBlock = doc.body ;
 703  
 704      range.MoveToNodeContents( editBlock ) ;
 705      range.Collapse( true ) ;
 706      range.Select() ;
 707      range.Release() ;
 708  }


Generated: Mon Jul 9 18:01:44 2012 Cross-referenced by PHPXref 0.7