[ Index ]
 

Code source de FCKeditor 2.4

Accédez au Source d'autres logiciels libresSoutenez Angelica Josefina !

title

Body

[fermer]

/editor/_source/classes/ -> fckdomrange.js (source)

   1  /*
   2   * FCKeditor - The text editor for Internet - http://www.fckeditor.net
   3   * Copyright (C) 2003-2007 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   * File Name: fckdomrange.js
  22   *     Class for working with a selection range, much like the W3C DOM Range, but
  23   *     it is not intented to be an implementation of the W3C interface.
  24   * 
  25   * File Authors:
  26   *         Frederico Caldeira Knabben (www.fckeditor.net)
  27   */
  28  
  29  var FCKDomRange = function( sourceWindow )
  30  {
  31      this.Window = sourceWindow ;
  32  }
  33  
  34  FCKDomRange.prototype =
  35  {
  36  
  37      _UpdateElementInfo : function()
  38      {
  39          if ( !this._Range )
  40              this.Release( true ) ;
  41          else
  42          {
  43              var eStart    = this._Range.startContainer ;
  44              var eEnd    = this._Range.endContainer ;
  45              
  46              var oElementPath = new FCKElementPath( eStart ) ;
  47              this.StartContainer        = oElementPath.LastElement ;
  48              this.StartBlock            = oElementPath.Block ;
  49              this.StartBlockLimit    = oElementPath.BlockLimit ;
  50  
  51              if ( eStart != eEnd )
  52                  oElementPath = new FCKElementPath( eEnd ) ;
  53              this.EndContainer        = oElementPath.LastElement ;            
  54              this.EndBlock            = oElementPath.Block ;
  55              this.EndBlockLimit        = oElementPath.BlockLimit ;
  56          }
  57      },
  58  
  59      CreateRange : function()
  60      {
  61          return new FCKW3CRange( this.Window.document ) ;
  62      },
  63  
  64      DeleteContents : function()
  65      {
  66          if ( this._Range )
  67          {
  68              this._Range.deleteContents() ;
  69              this._UpdateElementInfo() ;
  70          }
  71      },
  72  
  73      ExtractContents : function()
  74      {
  75          if ( this._Range )
  76          {
  77              var docFrag = this._Range.extractContents() ;
  78              this._UpdateElementInfo() ;
  79              return docFrag ;
  80          }
  81      },
  82  
  83      CheckIsCollapsed : function()
  84      {
  85          if ( this._Range )    
  86              return this._Range.collapsed ;
  87      },
  88  
  89      Collapse : function( toStart )
  90      {
  91          if ( this._Range )
  92              this._Range.collapse( toStart ) ;
  93          
  94          this._UpdateElementInfo() ;
  95      },
  96  
  97      Clone : function()
  98      {
  99          var oClone = FCKTools.CloneObject( this ) ;
 100  
 101          if ( this._Range )
 102              oClone._Range = this._Range.cloneRange() ;
 103          
 104          return oClone ;
 105      },
 106  
 107      MoveToNodeContents : function( targetNode )
 108      {
 109          if ( !this._Range )
 110              this._Range = this.CreateRange() ;
 111  
 112          this._Range.selectNodeContents( targetNode ) ;
 113  
 114          this._UpdateElementInfo() ;
 115      },
 116  
 117      MoveToElementStart : function( targetElement )
 118      {
 119          this.SetStart(targetElement,1) ;
 120          this.SetEnd(targetElement,1) ;
 121      },
 122  
 123      InsertNode : function( node )
 124      {
 125          if ( this._Range )
 126              this._Range.insertNode( node ) ;
 127      },
 128  
 129      CheckIsEmpty : function( ignoreEndBRs )
 130      {
 131          if ( this.CheckIsCollapsed() )
 132              return true ;
 133  
 134          // Inserts the contents of the range in a div tag.
 135          var eToolDiv = this.Window.document.createElement( 'div' ) ;
 136          this._Range.cloneContents().AppendTo( eToolDiv ) ;
 137          
 138          FCKDomTools.TrimNode( eToolDiv, ignoreEndBRs ) ;
 139          
 140          return ( eToolDiv.innerHTML.length == 0 ) ;
 141      },
 142  
 143      CheckStartOfBlock : function()
 144      {
 145          // Create a clone of the current range.
 146          var oTestRange = this.Clone() ;
 147          
 148          // Collapse it to its start point.
 149          oTestRange.Collapse( true ) ;
 150          
 151          // Move the start boundary to the start of the block.
 152          oTestRange.SetStart( oTestRange.StartBlock || oTestRange.StartBlockLimit, 1 ) ;
 153          
 154          var bIsStartOfBlock = oTestRange.CheckIsEmpty() ;
 155  
 156          oTestRange.Release() ;
 157          
 158          return bIsStartOfBlock ;
 159      },
 160  
 161      CheckEndOfBlock : function( refreshSelection )
 162      {
 163          // Create a clone of the current range.
 164          var oTestRange = this.Clone() ;
 165          
 166          // Collapse it to its end point.
 167          oTestRange.Collapse( false ) ;
 168          
 169          // Move the end boundary to the end of the block.
 170          oTestRange.SetEnd( oTestRange.EndBlock || oTestRange.EndBlockLimit, 2 ) ;
 171  
 172          var bIsEndOfBlock = oTestRange.CheckIsEmpty( true ) ;
 173  
 174          oTestRange.Release() ;
 175          
 176          if ( refreshSelection ) 
 177              this.Select() ;
 178          
 179          return bIsEndOfBlock ;
 180      },
 181  
 182      CreateBookmark : function()
 183      {
 184          // Create the bookmark info (random IDs).
 185          var oBookmark = 
 186          {
 187              StartId    : 'fck_dom_range_start_' + (new Date()).valueOf() + '_' + Math.floor(Math.random()*1000),
 188              EndId    : 'fck_dom_range_end_' + (new Date()).valueOf() + '_' + Math.floor(Math.random()*1000)
 189          } ;
 190  
 191          var oDoc = this.Window.document ;
 192          var eSpan ;
 193          var oClone ;
 194  
 195          // For collapsed ranges, add just the start marker.
 196          if ( !this.CheckIsCollapsed() )
 197          {
 198              eSpan = oDoc.createElement( 'span' ) ;
 199              eSpan.id = oBookmark.EndId ;
 200              eSpan.innerHTML = ' ' ;    // For IE, it must have something inside, otherwise it may be removed during operations.
 201  
 202              oClone = this.Clone() ;
 203              oClone.Collapse( false ) ;
 204              oClone.InsertNode( eSpan ) ;
 205          }
 206          
 207          eSpan = oDoc.createElement( 'span' ) ;
 208          eSpan.id = oBookmark.StartId ;
 209          eSpan.innerHTML = ' ' ;    // For IE, it must have something inside, otherwise it may be removed during operations.
 210  
 211          oClone = this.Clone() ;
 212          oClone.Collapse( true ) ;
 213          oClone.InsertNode( eSpan ) ;
 214  
 215          return oBookmark ;
 216      },
 217  
 218      MoveToBookmark : function( bookmark, preserveBookmark )
 219      {
 220          var oDoc = this.Window.document ;
 221          
 222          var eStartSpan    =  oDoc.getElementById( bookmark.StartId ) ;
 223          var eEndSpan    =  oDoc.getElementById( bookmark.EndId ) ;
 224  
 225          this.SetStart( eStartSpan, 3 ) ;
 226          
 227          if ( !preserveBookmark )
 228              FCKDomTools.RemoveNode( eStartSpan ) ;
 229  
 230          // If collapsed, the start span will not be available.
 231          if ( eEndSpan )
 232          {
 233              this.SetEnd( eEndSpan, 3 ) ;
 234              
 235              if ( !preserveBookmark )
 236                  FCKDomTools.RemoveNode( eEndSpan ) ;
 237          }
 238          else
 239              this.Collapse( true ) ;
 240      },
 241  
 242      /*
 243       * Moves the position of the start boundary of the range to a specific position
 244       * relatively to a element.
 245       *        @position:
 246       *            1 = After Start        <target>^contents</target>
 247       *            2 = Before End        <target>contents^</target>
 248       *            3 = Before Start    ^<target>contents</target>
 249       *            4 = After End        <target>contents</target>^
 250       */
 251      SetStart : function( targetElement, position )
 252      {
 253          var oRange = this._Range ;
 254          if ( !oRange )
 255              oRange = this._Range = this.CreateRange() ;
 256  
 257          switch( position )
 258          {
 259              case 1 :        // After Start        <target>^contents</target>    
 260                  oRange.setStart( targetElement, 0 ) ;
 261                  break ;
 262  
 263              case 2 :        // Before End        <target>contents^</target>
 264                  oRange.setStart( targetElement, targetElement.childNodes.length ) ;
 265                  break ;
 266  
 267              case 3 :        // Before Start        ^<target>contents</target>
 268                  oRange.setStartBefore( targetElement ) ;
 269                  break ;
 270              
 271              case 4 :        // After End        <target>contents</target>^
 272                  oRange.setStartAfter( targetElement ) ;
 273          }
 274          this._UpdateElementInfo() ;
 275      },
 276  
 277      /*
 278       * Moves the position of the start boundary of the range to a specific position
 279       * relatively to a element.
 280       *        @position:
 281       *            1 = After Start        <target>^contents</target>
 282       *            2 = Before End        <target>contents^</target>
 283       *            3 = Before Start    ^<target>contents</target>
 284       *            4 = After End        <target>contents</target>^
 285       */
 286      SetEnd : function( targetElement, position )
 287      {
 288          var oRange = this._Range ;
 289          if ( !oRange )
 290              oRange = this._Range = this.CreateRange() ;
 291          
 292          switch( position )
 293          {
 294              case 1 :        // After Start        <target>^contents</target>
 295                  oRange.setEnd( targetElement, 0 ) ;
 296                  break ;
 297  
 298              case 2 :        // Before End        <target>contents^</target>
 299                  oRange.setEnd( targetElement, targetElement.childNodes.length ) ;
 300                  break ;
 301  
 302              case 3 :        // Before Start        ^<target>contents</target>
 303                  oRange.setEndBefore( targetElement ) ;
 304                  break ;
 305              
 306              case 4 :        // After End        <target>contents</target>^
 307                  oRange.setEndAfter( targetElement ) ;
 308          }
 309          this._UpdateElementInfo() ;
 310      },
 311  
 312      Expand : function( unit )
 313      {
 314          var oNode, oSibling ;
 315  
 316          switch ( unit )
 317          {
 318              case 'block_contents' :
 319                  if ( this.StartBlock )
 320                      this.SetStart( this.StartBlock, 1 ) ;
 321                  else
 322                  {
 323                      // Get the start node for the current range.
 324                      oNode = this._Range.startContainer ;
 325                      
 326                      // If it is an element, get the current child node for the range (in the offset).
 327                      // If the offset node is not available, the the first one.
 328                      if ( oNode.nodeType == 1 )
 329                      {
 330                          if ( !( oNode = oNode.childNodes[ this._Range.startOffset ] ) )
 331                              oNode = oNode.firstChild ;
 332                      }
 333                      
 334                      // Not able to defined the current position.
 335                      if ( !oNode )
 336                          return ;
 337                      
 338                      // We must look for the left boundary, relative to the range
 339                      // start, which is limited by a block element.
 340                      while ( true )
 341                      {
 342                          oSibling = oNode.previousSibling ;
 343                          
 344                          if ( !oSibling )
 345                          {
 346                              // Continue if we are not yet in the block limit (inside a <b>, for example).
 347                              if ( oNode.parentNode != this.StartBlockLimit )
 348                                  oNode = oNode.parentNode ;
 349                              else
 350                                  break ;
 351                          }
 352                          else if ( oSibling.nodeType != 1 || !(/^(?:P|DIV|H1|H2|H3|H4|H5|H6|ADDRESS|PRE|OL|UL|LI|DT|DE)$/).test( oSibling.nodeName.toUpperCase() ) )
 353                          {
 354                              // Continue if the sibling is not a block tag.
 355                              oNode = oSibling ;
 356                          }
 357                          else
 358                              break ;
 359                      }
 360                      
 361                      this._Range.setStartBefore( oNode ) ;
 362                  }
 363                  
 364                  if ( this.EndBlock )
 365                      this.SetEnd( this.EndBlock, 2 ) ;
 366                  else
 367                  {
 368                      oNode = this._Range.endContainer ;
 369                      if ( oNode.nodeType == 1 )
 370                          oNode = oNode.childNodes[ this._Range.endOffset ] || oNode.lastChild ;
 371                      
 372                      if ( !oNode )
 373                          return ;
 374                      
 375                      // We must look for the right boundary, relative to the range
 376                      // end, which is limited by a block element.
 377                      while ( true )
 378                      {
 379                          oSibling = oNode.nextSibling ;
 380                          
 381                          if ( !oSibling )
 382                          {
 383                              // Continue if we are not yet in the block limit (inide a <b>, for example).
 384                              if ( oNode.parentNode != this.EndBlockLimit )
 385                                  oNode = oNode.parentNode ;
 386                              else
 387                                  break ;
 388                          }
 389                          else if ( oSibling.nodeType != 1 || !(/^(?:P|DIV|H1|H2|H3|H4|H5|H6|ADDRESS|PRE|OL|UL|LI|DT|DE)$/).test( oSibling.nodeName.toUpperCase() ) )
 390                          {
 391                              // Continue if the sibling is not a block tag.
 392                              oNode = oSibling ;
 393                          }
 394                          else
 395                              break ;
 396                      }
 397                      
 398                      this._Range.setEndAfter( oNode ) ;
 399                  }
 400  
 401                  this._UpdateElementInfo() ;
 402          }
 403      },
 404  
 405      Release : function( preserveWindow )
 406      {
 407          if ( !preserveWindow )
 408              this.Window = null ;
 409  
 410          this.StartContainer = null ;
 411          this.StartBlock = null ;
 412          this.StartBlockLimit = null ;
 413          this.EndContainer = null ;
 414          this.EndBlock = null ;
 415          this.EndBlockLimit = null ;
 416          this._Range = null ;
 417      }
 418  } ;


Généré le : Sun Feb 25 15:28:05 2007 par Balluche grâce à PHPXref 0.7