[ Index ]

PHP Cross Reference of Drupal 6 (yi-drupal)

title

Body

[close]

/sites/all/modules/fckeditor/fckeditor/editor/_source/internals/ -> fckstyles.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   * Handles styles in a give document.

  22   */
  23  
  24  var FCKStyles = FCK.Styles =
  25  {
  26      _Callbacks : {},
  27      _ObjectStyles : {},
  28  
  29      ApplyStyle : function( style )
  30      {
  31          if ( typeof style == 'string' )
  32              style = this.GetStyles()[ style ] ;
  33  
  34          if ( style )
  35          {
  36              if ( style.GetType() == FCK_STYLE_OBJECT )
  37                  style.ApplyToObject( FCKSelection.GetSelectedElement() ) ;
  38              else
  39                  style.ApplyToSelection( FCK.EditorWindow ) ;
  40  
  41              FCK.Events.FireEvent( 'OnSelectionChange' ) ;
  42          }
  43      },
  44  
  45      RemoveStyle : function( style )
  46      {
  47          if ( typeof style == 'string' )
  48              style = this.GetStyles()[ style ] ;
  49  
  50          if ( style )
  51          {
  52              style.RemoveFromSelection( FCK.EditorWindow ) ;
  53              FCK.Events.FireEvent( 'OnSelectionChange' ) ;
  54          }
  55      },
  56  
  57      /**

  58       * Defines a callback function to be called when the current state of a

  59       * specific style changes.

  60       */
  61      AttachStyleStateChange : function( styleName, callback, callbackOwner )
  62      {
  63          var callbacks = this._Callbacks[ styleName ] ;
  64  
  65          if ( !callbacks )
  66              callbacks = this._Callbacks[ styleName ] = [] ;
  67  
  68          callbacks.push( [ callback, callbackOwner ] ) ;
  69      },
  70  
  71      CheckSelectionChanges : function()
  72      {
  73          var startElement = FCKSelection.GetBoundaryParentElement( true ) ;
  74  
  75          if ( !startElement )
  76              return ;
  77  
  78          // Walks the start node parents path, checking all styles that are being listened.

  79          var path = new FCKElementPath( startElement ) ;
  80          var styles = this.GetStyles() ;
  81  
  82          for ( var styleName in styles )
  83          {
  84              var callbacks = this._Callbacks[ styleName ] ;
  85  
  86              if ( callbacks )
  87              {
  88                  var style = styles[ styleName ] ;
  89                  var state = style.CheckActive( path ) ;
  90  
  91                  if ( state != ( style._LastState || null ) )
  92                  {
  93                      style._LastState = state ;
  94  
  95                      for ( var i = 0 ; i < callbacks.length ; i++ )
  96                      {
  97                          var callback = callbacks[i][0] ;
  98                          var callbackOwner = callbacks[i][1] ;
  99  
 100                          callback.call( callbackOwner || window, styleName, state ) ;
 101                      }
 102                  }
 103              }
 104          }
 105      },
 106  
 107      CheckStyleInSelection : function( styleName )
 108      {
 109          return false ;
 110      },
 111  
 112      _GetRemoveFormatTagsRegex : function ()
 113      {
 114          var regex = new RegExp( '^(?:' + FCKConfig.RemoveFormatTags.replace( /,/g,'|' ) + ')$', 'i' ) ;
 115  
 116          return (this._GetRemoveFormatTagsRegex = function()
 117          {
 118              return regex ;
 119          })
 120          && regex  ;
 121      },
 122  
 123      /**

 124       * Remove all styles from the current selection.

 125       * TODO:

 126       *  - This is almost a duplication of FCKStyle.RemoveFromRange. We should

 127       *    try to merge things.

 128       */
 129      RemoveAll : function()
 130      {
 131          var range = new FCKDomRange( FCK.EditorWindow ) ;
 132          range.MoveToSelection() ;
 133  
 134          if ( range.CheckIsCollapsed() )
 135              return ;
 136  
 137              // Expand the range, if inside inline element boundaries.

 138          range.Expand( 'inline_elements' ) ;
 139  
 140          // Get the bookmark nodes.

 141          // Bookmark the range so we can re-select it after processing.

 142          var bookmark = range.CreateBookmark( true ) ;
 143  
 144          // The style will be applied within the bookmark boundaries.

 145          var startNode    = range.GetBookmarkNode( bookmark, true ) ;
 146          var endNode        = range.GetBookmarkNode( bookmark, false ) ;
 147  
 148          range.Release( true ) ;
 149  
 150          var tagsRegex = this._GetRemoveFormatTagsRegex() ;
 151  
 152          // We need to check the selection boundaries (bookmark spans) to break

 153          // the code in a way that we can properly remove partially selected nodes.

 154          // For example, removing a <b> style from

 155          //        <b>This is [some text</b> to show <b>the] problem</b>

 156          // ... where [ and ] represent the selection, must result:

 157          //        <b>This is </b>[some text to show the]<b> problem</b>

 158          // The strategy is simple, we just break the partial nodes before the

 159          // removal logic, having something that could be represented this way:

 160          //        <b>This is </b>[<b>some text</b> to show <b>the</b>]<b> problem</b>

 161  
 162          // Let's start checking the start boundary.

 163          var path = new FCKElementPath( startNode ) ;
 164          var pathElements = path.Elements ;
 165          var pathElement ;
 166  
 167          for ( var i = 1 ; i < pathElements.length ; i++ )
 168          {
 169              pathElement = pathElements[i] ;
 170  
 171              if ( pathElement == path.Block || pathElement == path.BlockLimit )
 172                  break ;
 173  
 174              // If this element can be removed (even partially).

 175              if ( tagsRegex.test( pathElement.nodeName ) )
 176                  FCKDomTools.BreakParent( startNode, pathElement, range ) ;
 177          }
 178  
 179          // Now the end boundary.

 180          path = new FCKElementPath( endNode ) ;
 181          pathElements = path.Elements ;
 182  
 183          for ( var i = 1 ; i < pathElements.length ; i++ )
 184          {
 185              pathElement = pathElements[i] ;
 186  
 187              if ( pathElement == path.Block || pathElement == path.BlockLimit )
 188                  break ;
 189  
 190              elementName = pathElement.nodeName.toLowerCase() ;
 191  
 192              // If this element can be removed (even partially).

 193              if ( tagsRegex.test( pathElement.nodeName ) )
 194                  FCKDomTools.BreakParent( endNode, pathElement, range ) ;
 195          }
 196  
 197          // Navigate through all nodes between the bookmarks.

 198          var currentNode = FCKDomTools.GetNextSourceNode( startNode, true, 1 ) ;
 199  
 200          while ( currentNode )
 201          {
 202              // If we have reached the end of the selection, stop looping.

 203              if ( currentNode == endNode )
 204                  break ;
 205  
 206              // Cache the next node to be processed. Do it now, because

 207              // currentNode may be removed.

 208              var nextNode = FCKDomTools.GetNextSourceNode( currentNode, false, 1 ) ;
 209  
 210              // Remove elements nodes that match with this style rules.

 211              if ( tagsRegex.test( currentNode.nodeName ) )
 212                  FCKDomTools.RemoveNode( currentNode, true ) ;
 213              else
 214                  FCKDomTools.RemoveAttributes( currentNode, FCKConfig.RemoveAttributesArray );
 215  
 216              currentNode = nextNode ;
 217          }
 218  
 219          range.SelectBookmark( bookmark ) ;
 220  
 221          FCK.Events.FireEvent( 'OnSelectionChange' ) ;
 222      },
 223  
 224      GetStyle : function( styleName )
 225      {
 226          return this.GetStyles()[ styleName ] ;
 227      },
 228  
 229      GetStyles : function()
 230      {
 231          var styles = this._GetStyles ;
 232          if ( !styles )
 233          {
 234              styles = this._GetStyles = FCKTools.Merge(
 235                  this._LoadStylesCore(),
 236                  this._LoadStylesCustom(),
 237                  this._LoadStylesXml() ) ;
 238          }
 239          return styles ;
 240      },
 241  
 242      CheckHasObjectStyle : function( elementName )
 243      {
 244          return !!this._ObjectStyles[ elementName ] ;
 245      },
 246  
 247      _LoadStylesCore : function()
 248      {
 249          var styles = {};
 250          var styleDefs = FCKConfig.CoreStyles ;
 251  
 252          for ( var styleName in styleDefs )
 253          {
 254              // Core styles are prefixed with _FCK_.

 255              var style = styles[ '_FCK_' + styleName ] = new FCKStyle( styleDefs[ styleName ] ) ;
 256              style.IsCore = true ;
 257          }
 258          return styles ;
 259      },
 260  
 261      _LoadStylesCustom : function()
 262      {
 263          var styles = {};
 264          var styleDefs = FCKConfig.CustomStyles ;
 265  
 266          if ( styleDefs )
 267          {
 268              for ( var styleName in styleDefs )
 269              {
 270                  var style = styles[ styleName ] = new FCKStyle( styleDefs[ styleName ] ) ;
 271                  style.Name = styleName ;
 272              }
 273          }
 274  
 275          return styles ;
 276      },
 277  
 278      _LoadStylesXml : function()
 279      {
 280          var styles = {};
 281  
 282          var stylesXmlPath = FCKConfig.StylesXmlPath ;
 283  
 284          if ( !stylesXmlPath || stylesXmlPath.length == 0 )
 285              return styles ;
 286  
 287          // Load the XML file into a FCKXml object.

 288          var xml = new FCKXml() ;
 289          xml.LoadUrl( stylesXmlPath ) ;
 290  
 291          var stylesXmlObj = FCKXml.TransformToObject( xml.SelectSingleNode( 'Styles' ) ) ;
 292  
 293          // Get the "Style" nodes defined in the XML file.

 294          var styleNodes = stylesXmlObj.$Style ;
 295  
 296          // Check that it did contain some valid nodes

 297          if ( !styleNodes )
 298              return styles ;
 299  
 300          // Add each style to our "Styles" collection.

 301          for ( var i = 0 ; i < styleNodes.length ; i++ )
 302          {
 303              var styleNode = styleNodes[i] ;
 304  
 305              var element = ( styleNode.element || '' ).toLowerCase() ;
 306  
 307              if ( element.length == 0 )
 308                  throw( 'The element name is required. Error loading "' + stylesXmlPath + '"' ) ;
 309  
 310              var styleDef = {
 311                  Element : element,
 312                  Attributes : {},
 313                  Styles : {},
 314                  Overrides : []
 315              } ;
 316  
 317              // Get the attributes defined for the style (if any).

 318              var attNodes = styleNode.$Attribute || [] ;
 319  
 320              // Add the attributes to the style definition object.

 321              for ( var j = 0 ; j < attNodes.length ; j++ )
 322              {
 323                  styleDef.Attributes[ attNodes[j].name ] = attNodes[j].value ;
 324              }
 325  
 326              // Get the styles defined for the style (if any).

 327              var cssStyleNodes = styleNode.$Style || [] ;
 328  
 329              // Add the attributes to the style definition object.

 330              for ( j = 0 ; j < cssStyleNodes.length ; j++ )
 331              {
 332                  styleDef.Styles[ cssStyleNodes[j].name ] = cssStyleNodes[j].value ;
 333              }
 334  
 335              // Load override definitions.

 336              var cssStyleOverrideNodes = styleNode.$Override ;
 337              if ( cssStyleOverrideNodes )
 338              {
 339                  for ( j = 0 ; j < cssStyleOverrideNodes.length ; j++ )
 340                  {
 341                      var overrideNode = cssStyleOverrideNodes[j] ;
 342                      var overrideDef =
 343                      {
 344                          Element : overrideNode.element
 345                      } ;
 346  
 347                      var overrideAttNode = overrideNode.$Attribute ;
 348                      if ( overrideAttNode )
 349                      {
 350                          overrideDef.Attributes = {} ;
 351                          for ( var k = 0 ; k < overrideAttNode.length ; k++ )
 352                          {
 353                              var overrideAttValue = overrideAttNode[k].value || null ;
 354                              if ( overrideAttValue )
 355                              {
 356                                  // Check if the override attribute value is a regular expression.

 357                                  var regexMatch = overrideAttValue && FCKRegexLib.RegExp.exec( overrideAttValue ) ;
 358                                  if ( regexMatch )
 359                                      overrideAttValue = new RegExp( regexMatch[1], regexMatch[2] || '' ) ;
 360                              }
 361                              overrideDef.Attributes[ overrideAttNode[k].name ] = overrideAttValue ;
 362                          }
 363                      }
 364  
 365                      styleDef.Overrides.push( overrideDef ) ;
 366                  }
 367              }
 368  
 369              var style = new FCKStyle( styleDef ) ;
 370              style.Name = styleNode.name || element ;
 371  
 372              if ( style.GetType() == FCK_STYLE_OBJECT )
 373                  this._ObjectStyles[ element ] = true ;
 374  
 375              // Add the style to the "Styles" collection using it's name as the key.

 376              styles[ style.Name ] = style ;
 377          }
 378  
 379          return styles ;
 380      }
 381  } ;


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