Changeset 5709


Ignore:
Timestamp:
07/20/10 15:24:22 (4 years ago)
Author:
fredck
Message:

Merged the contenteditable feature branch.

Location:
CKEditor/branches/versions/3.4.x
Files:
34 edited
1 copied

Legend:

Unmodified
Added
Removed
  • CKEditor/branches/versions/3.4.x

  • CKEditor/branches/versions/3.4.x/CHANGES.html

    r5692 r5709  
    4444                <li><a href="http://dev.fckeditor.net/ticket/5909">#5909</a> : BiDi: Support for switching base language.</li> 
    4545                <li><a href="http://dev.fckeditor.net/ticket/4606">#4606</a> : Port 'AutoGrow' plugin from FCKEditor 2.x.</li> 
     46                <li><a href="http://dev.fckeditor.net/ticket/5737">#5737</a> : Added support for the <a href="http://www.w3.org/TR/html5/editing.html#contenteditable">HTML5 contenteditable attribute</a>, making it possible to define read only regions into the editor contents.</li> 
    4647        </ul> 
    4748        <p> 
  • CKEditor/branches/versions/3.4.x/_dev/releaser/ckreleaser.release

  • CKEditor/branches/versions/3.4.x/_dev/releaser/release.bat

  • CKEditor/branches/versions/3.4.x/_source/core/dom/node.js

    r5189 r5709  
    658658                                } 
    659659                        } 
     660                }, 
     661 
     662                isReadOnly : function() 
     663                { 
     664                        var current = this; 
     665                        while( current ) 
     666                        { 
     667                                if ( current.type == CKEDITOR.NODE_ELEMENT ) 
     668                                { 
     669                                        if ( current.is ( 'body' ) ) 
     670                                                break; 
     671 
     672                                        if ( current.getAttribute( 'contentEditable' ) == 'false' ) 
     673                                                return current; 
     674                                        else if ( current.getAttribute( 'contentEditable' ) == 'true' ) 
     675                                                break; 
     676                                } 
     677                                current = current.getParent(); 
     678                        } 
     679 
     680                        return false; 
    660681                } 
    661682        } 
  • CKEditor/branches/versions/3.4.x/_source/core/dom/range.js

    r5656 r5709  
    1 /* 
     1/* 
    22Copyright (c) 2003-2010, CKSource - Frederico Knabben. All rights reserved. 
    33For licensing, see LICENSE.html or http://ckeditor.com/license 
  • CKEditor/branches/versions/3.4.x/_source/core/loader.js

    r5106 r5709  
    1 /* 
     1/* 
    22Copyright (c) 2003-2010, CKSource - Frederico Knabben. All rights reserved. 
    33For licensing, see LICENSE.html or http://ckeditor.com/license 
     
    2424                var scripts = 
    2525                { 
    26                         'core/_bootstrap'               : [ 'core/config', 'core/ckeditor', 'core/plugins', 'core/scriptloader', 'core/tools', /* The following are entries that we want to force loading at the end to avoid dependence recursion */ 'core/dom/comment', 'core/dom/elementpath', 'core/dom/text', 'core/dom/range' ], 
     26                        'core/_bootstrap'               : [ 'core/config', 'core/ckeditor', 'core/plugins', 'core/scriptloader', 'core/tools', /* The following are entries that we want to force loading at the end to avoid dependence recursion */ 'core/dom/comment', 'core/dom/elementpath', 'core/dom/text', 'core/dom/rangelist' ], 
    2727                        'core/ajax'                             : [ 'core/xml' ], 
    2828                        'core/ckeditor'                 : [ 'core/ckeditor_basic', 'core/dom', 'core/dtd', 'core/dom/document', 'core/dom/element', 'core/editor', 'core/event', 'core/htmlparser', 'core/htmlparser/element', 'core/htmlparser/fragment', 'core/htmlparser/filter', 'core/htmlparser/basicwriter', 'core/tools' ], 
     
    4242                        'core/dom/domobject'    : [ 'core/dom/event' ], 
    4343                        'core/dom/range'                : [ 'core/dom/document', 'core/dom/documentfragment', 'core/dom/element', 'core/dom/walker' ], 
     44                        'core/dom/rangelist'    : [ 'core/dom/range' ], 
    4445                        'core/dom/text'                 : [ 'core/dom/node', 'core/dom/domobject' ], 
    4546                        'core/dom/walker'               : [ 'core/dom/node' ], 
  • CKEditor/branches/versions/3.4.x/_source/plugins/blockquote/plugin.js

    r5206 r5709  
    4848                        var state = editor.getCommand( 'blockquote' ).state, 
    4949                                selection = editor.getSelection(), 
    50                                 range = selection && selection.getRanges()[0]; 
     50                                range = selection && selection.getRanges( true )[0]; 
    5151 
    5252                        if ( !range ) 
  • CKEditor/branches/versions/3.4.x/_source/plugins/clipboard/plugin.js

    r5534 r5709  
    1 /* 
     1/* 
    22Copyright (c) 2003-2010, CKSource - Frederico Knabben. All rights reserved. 
    33For licensing, see LICENSE.html or http://ckeditor.com/license 
     
    387387                                        } 
    388388 
    389                                         editor.contextMenu.addListener( function() 
     389                                        editor.contextMenu.addListener( function( element, selection ) 
    390390                                                { 
     391                                                        var readOnly = selection.getCommonAncestor().isReadOnly(); 
    391392                                                        return { 
    392                                                                 cut : stateFromNamedCommand( 'Cut' ), 
     393                                                                cut : !readOnly && stateFromNamedCommand( 'Cut' ), 
    393394 
    394395                                                                // Browser bug: 'Cut' has the correct states for both Copy and Cut. 
    395396                                                                copy : stateFromNamedCommand( 'Cut' ), 
    396                                                                 paste : CKEDITOR.env.webkit ? CKEDITOR.TRISTATE_OFF : stateFromNamedCommand( 'Paste' ) 
     397                                                                paste : !readOnly && ( CKEDITOR.env.webkit ? CKEDITOR.TRISTATE_OFF : stateFromNamedCommand( 'Paste' ) ) 
    397398                                                        }; 
    398399                                                }); 
  • CKEditor/branches/versions/3.4.x/_source/plugins/div/dialogs/div.js

  • CKEditor/branches/versions/3.4.x/_source/plugins/div/plugin.js

    r5656 r5709  
    9696                                        editor.contextMenu.addListener( function( element, selection ) 
    9797                                                { 
    98                                                         if ( !element ) 
     98                                                        if ( !element || element.isReadOnly()) 
    9999                                                                return null; 
    100100 
  • CKEditor/branches/versions/3.4.x/_source/plugins/enterkey/plugin.js

    r5534 r5709  
    2424                        // Get the range for the current selection. 
    2525                        range = range || getRange( editor ); 
     26 
     27                        // We may not have valid ranges to work on, like when inside a 
     28                        // contenteditable=false element. 
     29                        if ( !range ) 
     30                                return; 
    2631 
    2732                        var doc = range.document; 
     
    189194                        // Get the range for the current selection. 
    190195                        range = range || getRange( editor ); 
     196 
     197                        // We may not have valid ranges to work on, like when inside a 
     198                        // contenteditable=false element. 
     199                        if ( !range ) 
     200                                return; 
    191201 
    192202                        var doc = range.document; 
     
    340350        { 
    341351                // Get the selection ranges. 
    342                 var ranges = editor.getSelection().getRanges(); 
     352                var ranges = editor.getSelection().getRanges( true ); 
    343353 
    344354                // Delete the contents of all ranges except the first one. 
  • CKEditor/branches/versions/3.4.x/_source/plugins/find/dialogs/find.js

    r5606 r5709  
    1 /* 
     1/* 
    22Copyright (c) 2003-2010, CKSource - Frederico Knabben. All rights reserved. 
    33For licensing, see LICENSE.html or http://ckeditor.com/license 
     
    66(function() 
    77{ 
    8         function nonEmptyText( node ) 
     8        function findEvaluator( node ) 
    99        { 
    10                 return ( node.type == CKEDITOR.NODE_TEXT && node.getLength() > 0 ); 
     10                return node.type == CKEDITOR.NODE_TEXT && node.getLength() > 0 && !node.isReadOnly(); 
    1111        } 
    1212 
     
    1414         * Elements which break characters been considered as sequence. 
    1515        */ 
    16         function nonCharactersBoundary ( node ) 
     16        function nonCharactersBoundary( node ) 
    1717        { 
    1818                return !( node.type == CKEDITOR.NODE_ELEMENT && node.isBlockBoundary( 
     
    8585                                new CKEDITOR.dom.walker( range ); 
    8686                        walker.guard = matchWord ? nonCharactersBoundary : null; 
    87                         walker[ 'evaluator' ] = nonEmptyText; 
     87                        walker[ 'evaluator' ] = findEvaluator; 
    8888                        walker.breakOnFalse = true; 
    8989 
     
    252252 
    253253                                // Apply the highlight. 
    254                                 var range = this.toDomRange(); 
     254                                var range = this.toDomRange(), 
     255                                        bookmark = range.createBookmark(); 
    255256                                highlightStyle.applyToRange( range ); 
     257                                range.moveToBookmark( bookmark ); 
    256258                                this._.highlightRange = range; 
    257259 
     
    274276                                        return; 
    275277 
     278                                var bookmark = this._.highlightRange.createBookmark(); 
    276279                                highlightStyle.removeFromRange( this._.highlightRange ); 
     280                                this._.highlightRange.moveToBookmark( bookmark ); 
    277281                                this.updateFromDomRange( this._.highlightRange ); 
    278282                                this._.highlightRange = null; 
  • CKEditor/branches/versions/3.4.x/_source/plugins/flash/plugin.js

    r5548 r5709  
    9191                                editor.contextMenu.addListener( function( element, selection ) 
    9292                                        { 
    93                                                 if ( element && element.is( 'img' ) && element.getAttribute( '_cke_real_element_type' ) == 'flash' ) 
     93                                                if ( element && element.is( 'img' ) && !element.isReadOnly() 
     94                                                                && element.getAttribute( '_cke_real_element_type' ) == 'flash' ) 
    9495                                                        return { flash : CKEDITOR.TRISTATE_OFF }; 
    9596                                        }); 
  • CKEditor/branches/versions/3.4.x/_source/plugins/forms/plugin.js

    r5656 r5709  
    1 /* 
     1/* 
    22Copyright (c) 2003-2010, CKSource - Frederico Knabben. All rights reserved. 
    33For licensing, see LICENSE.html or http://ckeditor.com/license 
     
    132132                        editor.contextMenu.addListener( function( element ) 
    133133                                { 
    134                                         if ( element && element.hasAscendant( 'form', true ) ) 
     134                                        if ( element && element.hasAscendant( 'form', true ) && !element.isReadOnly() ) 
    135135                                                return { form : CKEDITOR.TRISTATE_OFF }; 
    136136                                }); 
     
    138138                        editor.contextMenu.addListener( function( element ) 
    139139                                { 
    140                                         if ( element ) 
     140                                        if ( element && !element.isReadOnly() ) 
    141141                                        { 
    142142                                                var name = element.getName(); 
  • CKEditor/branches/versions/3.4.x/_source/plugins/image/plugin.js

    r5548 r5709  
    5454                        editor.contextMenu.addListener( function( element, selection ) 
    5555                                { 
    56                                         if ( !element || !element.is( 'img' ) || element.getAttribute( '_cke_realelement' ) ) 
     56                                        if ( !element || !element.is( 'img' ) || element.getAttribute( '_cke_realelement' ) || element.isReadOnly() ) 
    5757                                                return null; 
    5858 
  • CKEditor/branches/versions/3.4.x/_source/plugins/indent/plugin.js

    r5548 r5709  
    6363        } 
    6464 
    65         function indentList( editor, range, listNode ) 
    66         { 
    67                 // Our starting and ending points of the range might be inside some blocks under a list item... 
    68                 // So before playing with the iterator, we need to expand the block to include the list items. 
    69                 var startContainer = range.startContainer, 
    70                         endContainer = range.endContainer; 
    71                 while ( startContainer && !startContainer.getParent().equals( listNode ) ) 
    72                         startContainer = startContainer.getParent(); 
    73                 while ( endContainer && !endContainer.getParent().equals( listNode ) ) 
    74                         endContainer = endContainer.getParent(); 
    75  
    76                 if ( !startContainer || !endContainer ) 
    77                         return; 
    78  
    79                 // Now we can iterate over the individual items on the same tree depth. 
    80                 var block = startContainer, 
    81                         itemsToMove = [], 
    82                         stopFlag = false; 
    83                 while ( !stopFlag ) 
    84                 { 
    85                         if ( block.equals( endContainer ) ) 
    86                                 stopFlag = true; 
    87                         itemsToMove.push( block ); 
    88                         block = block.getNext(); 
    89                 } 
    90                 if ( itemsToMove.length < 1 ) 
    91                         return; 
    92  
    93                 // Do indent or outdent operations on the array model of the list, not the 
    94                 // list's DOM tree itself. The array model demands that it knows as much as 
    95                 // possible about the surrounding lists, we need to feed it the further 
    96                 // ancestor node that is still a list. 
    97                 var listParents = listNode.getParents( true ); 
    98                 for ( var i = 0 ; i < listParents.length ; i++ ) 
    99                 { 
    100                         if ( listParents[i].getName && listNodeNames[ listParents[i].getName() ] ) 
    101                         { 
    102                                 listNode = listParents[i]; 
    103                                 break; 
    104                         } 
    105                 } 
    106                 var indentOffset = this.name == 'indent' ? 1 : -1, 
    107                         startItem = itemsToMove[0], 
    108                         lastItem = itemsToMove[ itemsToMove.length - 1 ], 
    109                         database = {}; 
    110  
    111                 // Convert the list DOM tree into a one dimensional array. 
    112                 var listArray = CKEDITOR.plugins.list.listToArray( listNode, database ); 
    113  
    114                 // Apply indenting or outdenting on the array. 
    115                 var baseIndent = listArray[ lastItem.getCustomData( 'listarray_index' ) ].indent; 
    116                 for ( i = startItem.getCustomData( 'listarray_index' ); i <= lastItem.getCustomData( 'listarray_index' ); i++ ) 
    117                 { 
    118                         listArray[ i ].indent += indentOffset; 
    119                         // Make sure the newly created sublist get a brand-new element of the same type. (#5372) 
    120                         var listRoot = listArray[ i ].parent; 
    121                         listArray[ i ].parent = new CKEDITOR.dom.element( listRoot.getName(), listRoot.getDocument() ); 
    122                 } 
    123  
    124                 for ( i = lastItem.getCustomData( 'listarray_index' ) + 1 ; 
    125                                 i < listArray.length && listArray[i].indent > baseIndent ; i++ ) 
    126                         listArray[i].indent += indentOffset; 
    127  
    128                 // Convert the array back to a DOM forest (yes we might have a few subtrees now). 
    129                 // And replace the old list with the new forest. 
    130                 var newList = CKEDITOR.plugins.list.arrayToList( listArray, database, null, editor.config.enterMode, 0 ); 
    131  
    132                 // Avoid nested <li> after outdent even they're visually same, 
    133                 // recording them for later refactoring.(#3982) 
    134                 if ( this.name == 'outdent' ) 
    135                 { 
    136                         var parentLiElement; 
    137                         if ( ( parentLiElement = listNode.getParent() ) && parentLiElement.is( 'li' ) ) 
    138                         { 
    139                                 var children = newList.listNode.getChildren(), 
    140                                         pendingLis = [], 
    141                                         count = children.count(), 
    142                                         child; 
    143  
    144                                 for ( i = count - 1 ; i >= 0 ; i-- ) 
    145                                 { 
    146                                         if ( ( child = children.getItem( i ) ) && child.is && child.is( 'li' )  ) 
    147                                                 pendingLis.push( child ); 
    148                                 } 
    149                         } 
    150                 } 
    151  
    152                 if ( newList ) 
    153                         newList.listNode.replace( listNode ); 
    154  
    155                 // Move the nested <li> to be appeared after the parent. 
    156                 if ( pendingLis && pendingLis.length ) 
    157                 { 
    158                         for (  i = 0; i < pendingLis.length ; i++ ) 
    159                         { 
    160                                 var li = pendingLis[ i ], 
    161                                         followingList = li; 
    162  
    163                                 // Nest preceding <ul>/<ol> inside current <li> if any. 
    164                                 while ( ( followingList = followingList.getNext() ) && 
    165                                            followingList.is && 
    166                                            followingList.getName() in listNodeNames ) 
    167                                 { 
    168                                         // IE requires a filler NBSP for nested list inside empty list item, 
    169                                         // otherwise the list item will be inaccessiable. (#4476) 
    170                                         if ( CKEDITOR.env.ie && !li.getFirst( function( node ){ return isNotWhitespaces( node ) && isNotBookmark( node ); } ) ) 
    171                                                 li.append( range.document.createText( '\u00a0' ) ); 
    172  
    173                                         li.append( followingList ); 
    174                                 } 
    175  
    176                                 li.insertAfter( parentLiElement ); 
    177                         } 
    178                 } 
    179  
    180                 // Clean up the markers. 
    181                 CKEDITOR.dom.element.clearAllMarkers( database ); 
    182         } 
    183  
    184         function indentBlock( editor, range ) 
    185         { 
    186                 var iterator = range.createIterator(), 
    187                         enterMode = editor.config.enterMode; 
    188                 iterator.enforceRealBlocks = true; 
    189                 iterator.enlargeBr = enterMode != CKEDITOR.ENTER_BR; 
    190                 var block; 
    191                 while ( ( block = iterator.getNextParagraph() ) ) 
    192                         indentElement.call( this, editor, block ); 
    193         } 
    194  
    195         function indentElement( editor, element ) 
    196                 { 
    197                         if ( this.useIndentClasses ) 
    198                         { 
    199                                 // Transform current class name to indent step index. 
    200                         var indentClass = element.$.className.match( this.classNameRegex ), 
    201                                         indentStep = 0; 
    202                                 if ( indentClass ) 
    203                                 { 
    204                                         indentClass = indentClass[1]; 
    205                                         indentStep = this.indentClassMap[ indentClass ]; 
    206                                 } 
    207  
    208                                 // Operate on indent step index, transform indent step index back to class 
    209                                 // name. 
    210                                 if ( this.name == 'outdent' ) 
    211                                         indentStep--; 
    212                                 else 
    213                                         indentStep++; 
    214  
    215                         if ( indentStep < 0 ) 
    216                                 return false; 
    217  
    218                                 indentStep = Math.min( indentStep, editor.config.indentClasses.length ); 
    219                                 indentStep = Math.max( indentStep, 0 ); 
    220                         var className = CKEDITOR.tools.ltrim( element.$.className.replace( this.classNameRegex, '' ) ); 
    221                                 if ( indentStep < 1 ) 
    222                                 element.$.className = className; 
    223                                 else 
    224                                 element.addClass( editor.config.indentClasses[ indentStep - 1 ] ); 
    225                         } 
    226                         else 
    227                         { 
    228                         var currentOffset = parseInt( element.getStyle( this.indentCssProperty ), 10 ); 
    229                                 if ( isNaN( currentOffset ) ) 
    230                                         currentOffset = 0; 
    231                                 currentOffset += ( this.name == 'indent' ? 1 : -1 ) * editor.config.indentOffset; 
    232  
    233                         if ( currentOffset < 0 ) 
    234                                 return false; 
    235  
    236                                 currentOffset = Math.max( currentOffset, 0 ); 
    237                                 currentOffset = Math.ceil( currentOffset / editor.config.indentOffset ) * editor.config.indentOffset; 
    238                         element.setStyle( this.indentCssProperty, currentOffset ? currentOffset + editor.config.indentUnit : '' ); 
    239                         if ( element.getAttribute( 'style' ) === '' ) 
    240                                 element.removeAttribute( 'style' ); 
    241                         } 
    242  
    243                 return true; 
    244                 } 
    245  
    24665        function indentCommand( editor, name ) 
    24766        { 
     
    26887                exec : function( editor ) 
    26988                { 
     89                        var self = this, database = {}; 
     90 
     91                        function indentList( listNode ) 
     92                        { 
     93                                // Our starting and ending points of the range might be inside some blocks under a list item... 
     94                                // So before playing with the iterator, we need to expand the block to include the list items. 
     95                                var startContainer = range.startContainer, 
     96                                        endContainer = range.endContainer; 
     97                                while ( startContainer && !startContainer.getParent().equals( listNode ) ) 
     98                                        startContainer = startContainer.getParent(); 
     99                                while ( endContainer && !endContainer.getParent().equals( listNode ) ) 
     100                                        endContainer = endContainer.getParent(); 
     101 
     102                                if ( !startContainer || !endContainer ) 
     103                                        return; 
     104 
     105                                // Now we can iterate over the individual items on the same tree depth. 
     106                                var block = startContainer, 
     107                                        itemsToMove = [], 
     108                                        stopFlag = false; 
     109                                while ( !stopFlag ) 
     110                                { 
     111                                        if ( block.equals( endContainer ) ) 
     112                                                stopFlag = true; 
     113                                        itemsToMove.push( block ); 
     114                                        block = block.getNext(); 
     115                                } 
     116                                if ( itemsToMove.length < 1 ) 
     117                                        return; 
     118 
     119                                // Do indent or outdent operations on the array model of the list, not the 
     120                                // list's DOM tree itself. The array model demands that it knows as much as 
     121                                // possible about the surrounding lists, we need to feed it the further 
     122                                // ancestor node that is still a list. 
     123                                var listParents = listNode.getParents( true ); 
     124                                for ( var i = 0 ; i < listParents.length ; i++ ) 
     125                                { 
     126                                        if ( listParents[i].getName && listNodeNames[ listParents[i].getName() ] ) 
     127                                        { 
     128                                                listNode = listParents[i]; 
     129                                                break; 
     130                                        } 
     131                                } 
     132                                var indentOffset = self.name == 'indent' ? 1 : -1, 
     133                                        startItem = itemsToMove[0], 
     134                                        lastItem = itemsToMove[ itemsToMove.length - 1 ]; 
     135 
     136                                // Convert the list DOM tree into a one dimensional array. 
     137                                var listArray = CKEDITOR.plugins.list.listToArray( listNode, database ); 
     138 
     139                                // Apply indenting or outdenting on the array. 
     140                                var baseIndent = listArray[ lastItem.getCustomData( 'listarray_index' ) ].indent; 
     141                                for ( i = startItem.getCustomData( 'listarray_index' ); i <= lastItem.getCustomData( 'listarray_index' ); i++ ) 
     142                                { 
     143                                        listArray[ i ].indent += indentOffset; 
     144                                        // Make sure the newly created sublist get a brand-new element of the same type. (#5372) 
     145                                        var listRoot = listArray[ i ].parent; 
     146                                        listArray[ i ].parent = new CKEDITOR.dom.element( listRoot.getName(), listRoot.getDocument() ); 
     147                                } 
     148 
     149                                for ( i = lastItem.getCustomData( 'listarray_index' ) + 1 ; 
     150                                                i < listArray.length && listArray[i].indent > baseIndent ; i++ ) 
     151                                        listArray[i].indent += indentOffset; 
     152 
     153                                // Convert the array back to a DOM forest (yes we might have a few subtrees now). 
     154                                // And replace the old list with the new forest. 
     155                                var newList = CKEDITOR.plugins.list.arrayToList( listArray, database, null, editor.config.enterMode, 0 ); 
     156 
     157                                // Avoid nested <li> after outdent even they're visually same, 
     158                                // recording them for later refactoring.(#3982) 
     159                                if ( self.name == 'outdent' ) 
     160                                { 
     161                                        var parentLiElement; 
     162                                        if ( ( parentLiElement = listNode.getParent() ) && parentLiElement.is( 'li' ) ) 
     163                                        { 
     164                                                var children = newList.listNode.getChildren(), 
     165                                                        pendingLis = [], 
     166                                                        count = children.count(), 
     167                                                        child; 
     168 
     169                                                for ( i = count - 1 ; i >= 0 ; i-- ) 
     170                                                { 
     171                                                        if ( ( child = children.getItem( i ) ) && child.is && child.is( 'li' )  ) 
     172                                                                pendingLis.push( child ); 
     173                                                } 
     174                                        } 
     175                                } 
     176 
     177                                if ( newList ) 
     178                                        newList.listNode.replace( listNode ); 
     179 
     180                                // Move the nested <li> to be appeared after the parent. 
     181                                if ( pendingLis && pendingLis.length ) 
     182                                { 
     183                                        for (  i = 0; i < pendingLis.length ; i++ ) 
     184                                        { 
     185                                                var li = pendingLis[ i ], 
     186                                                        followingList = li; 
     187 
     188                                                // Nest preceding <ul>/<ol> inside current <li> if any. 
     189                                                while ( ( followingList = followingList.getNext() ) && 
     190                                                           followingList.is && 
     191                                                           followingList.getName() in listNodeNames ) 
     192                                                { 
     193                                                        // IE requires a filler NBSP for nested list inside empty list item, 
     194                                                        // otherwise the list item will be inaccessiable. (#4476) 
     195                                                        if ( CKEDITOR.env.ie && !li.getFirst( function( node ){ return isNotWhitespaces( node ) && isNotBookmark( node ); } ) ) 
     196                                                                li.append( range.document.createText( '\u00a0' ) ); 
     197 
     198                                                        li.append( followingList ); 
     199                                                } 
     200 
     201                                                li.insertAfter( parentLiElement ); 
     202                                        } 
     203                                } 
     204                        } 
     205 
     206                        function indentBlock() 
     207                        { 
     208                                var iterator = range.createIterator(), 
     209                                        enterMode = editor.config.enterMode; 
     210                                iterator.enforceRealBlocks = true; 
     211                                iterator.enlargeBr = enterMode != CKEDITOR.ENTER_BR; 
     212                                var block; 
     213                                while ( ( block = iterator.getNextParagraph() ) ) 
     214                                        indentElement( block ); 
     215                        } 
     216 
     217                        function indentElement( element ) 
     218                        { 
     219                                if ( element.getCustomData( 'indent_processed' ) ) 
     220                                        return; 
     221 
     222                                if ( self.useIndentClasses ) 
     223                                { 
     224                                        // Transform current class name to indent step index. 
     225                                        var indentClass = element.$.className.match( self.classNameRegex ), 
     226                                                        indentStep = 0; 
     227                                        if ( indentClass ) 
     228                                        { 
     229                                                indentClass = indentClass[1]; 
     230                                                indentStep = self.indentClassMap[ indentClass ]; 
     231                                        } 
     232 
     233                                        // Operate on indent step index, transform indent step index back to class 
     234                                        // name. 
     235                                        if ( self.name == 'outdent' ) 
     236                                                indentStep--; 
     237                                        else 
     238                                                indentStep++; 
     239 
     240                                        if ( indentStep < 0 ) 
     241                                                return false; 
     242 
     243                                        indentStep = Math.min( indentStep, editor.config.indentClasses.length ); 
     244                                        indentStep = Math.max( indentStep, 0 ); 
     245                                        var className = CKEDITOR.tools.ltrim( element.$.className.replace( self.classNameRegex, '' ) ); 
     246                                        if ( indentStep < 1 ) 
     247                                                element.$.className = className; 
     248                                        else 
     249                                                element.addClass( editor.config.indentClasses[ indentStep - 1 ] ); 
     250                                } 
     251                                else 
     252                                { 
     253                                        var currentOffset = parseInt( element.getStyle( self.indentCssProperty ), 10 ); 
     254                                        if ( isNaN( currentOffset ) ) 
     255                                                currentOffset = 0; 
     256                                        currentOffset += ( self.name == 'indent' ? 1 : -1 ) * editor.config.indentOffset; 
     257 
     258                                        if ( currentOffset < 0 ) 
     259                                                return false; 
     260 
     261                                        currentOffset = Math.max( currentOffset, 0 ); 
     262                                        currentOffset = Math.ceil( currentOffset / editor.config.indentOffset ) * editor.config.indentOffset; 
     263                                        element.setStyle( self.indentCssProperty, currentOffset ? currentOffset + editor.config.indentUnit : '' ); 
     264                                        if ( element.getAttribute( 'style' ) === '' ) 
     265                                                element.removeAttribute( 'style' ); 
     266                                } 
     267 
     268                                CKEDITOR.dom.element.setMarker( database, element, 'indent_processed', true ); 
     269                                return true; 
     270                        } 
     271 
    270272                        var selection = editor.getSelection(), 
    271                                 range = selection && selection.getRanges()[0]; 
    272  
    273                         var startContainer = range.startContainer, 
    274                                 endContainer = range.endContainer, 
    275                                 rangeRoot = range.getCommonAncestor(), 
    276                                 nearestListBlock = rangeRoot; 
    277  
    278                         while ( nearestListBlock && !( nearestListBlock.type == CKEDITOR.NODE_ELEMENT && 
    279                                 listNodeNames[ nearestListBlock.getName() ] ) ) 
    280                                 nearestListBlock = nearestListBlock.getParent(); 
    281  
    282                         // Avoid selection anchors under list root. 
    283                         // <ul>[<li>...</li>]</ul> =>   <ul><li>[...]</li></ul> 
    284                         if ( nearestListBlock && startContainer.type == CKEDITOR.NODE_ELEMENT 
    285                                 && startContainer.getName() in listNodeNames ) 
    286                         { 
    287                                 var walker = new CKEDITOR.dom.walker( range ); 
    288                                 walker.evaluator = isListItem; 
    289                                 range.startContainer = walker.next(); 
    290                         } 
    291  
    292                         if ( nearestListBlock && endContainer.type == CKEDITOR.NODE_ELEMENT 
    293                                 && endContainer.getName() in listNodeNames ) 
    294                         { 
    295                                 walker = new CKEDITOR.dom.walker( range ); 
    296                                 walker.evaluator = isListItem; 
    297                                 range.endContainer = walker.previous(); 
    298                         } 
    299  
    300                         var bookmarks = selection.createBookmarks( true ); 
    301  
    302                         if ( nearestListBlock  ) 
    303                         { 
    304                                 var firstListItem = nearestListBlock.getFirst( function( node ) 
    305                                         { 
    306                                                 return node.type == CKEDITOR.NODE_ELEMENT && node.is( 'li' ); 
    307                                         }), 
    308                                         rangeStart = range.startContainer, 
    309                                         indentWholeList = firstListItem.equals( rangeStart ) || firstListItem.contains( rangeStart ); 
    310  
    311                                 // Indent the entire list if  cursor is inside the first list item. (#3893) 
    312                                 if ( !( indentWholeList && indentElement.call( this, editor, nearestListBlock ) ) ) 
    313                                 indentList.call( this, editor, range, nearestListBlock ); 
    314                         } 
    315                         else 
    316                                 indentBlock.call( this, editor, range ); 
    317  
    318                         editor.focus(); 
     273                                bookmarks = selection.createBookmarks( true ), 
     274                                ranges = selection && selection.getRanges( true ), 
     275                                range; 
     276 
     277                        var iterator = ranges.createIterator(); 
     278                        while ( range = iterator.getNextRange() ) 
     279                        { 
     280                                var startContainer = range.startContainer, 
     281                                        endContainer = range.endContainer, 
     282                                        rangeRoot = range.getCommonAncestor(), 
     283                                        nearestListBlock = rangeRoot; 
     284 
     285                                while ( nearestListBlock && !( nearestListBlock.type == CKEDITOR.NODE_ELEMENT && 
     286                                        listNodeNames[ nearestListBlock.getName() ] ) ) 
     287                                        nearestListBlock = nearestListBlock.getParent(); 
     288 
     289                                // Avoid selection anchors under list root. 
     290                                // <ul>[<li>...</li>]</ul> =>   <ul><li>[...]</li></ul> 
     291                                if ( nearestListBlock && startContainer.type == CKEDITOR.NODE_ELEMENT 
     292                                        && startContainer.getName() in listNodeNames ) 
     293                                { 
     294                                        var walker = new CKEDITOR.dom.walker( range ); 
     295                                        walker.evaluator = isListItem; 
     296                                        range.startContainer = walker.next(); 
     297                                } 
     298 
     299                                if ( nearestListBlock && endContainer.type == CKEDITOR.NODE_ELEMENT 
     300                                        && endContainer.getName() in listNodeNames ) 
     301                                { 
     302                                        walker = new CKEDITOR.dom.walker( range ); 
     303                                        walker.evaluator = isListItem; 
     304                                        range.endContainer = walker.previous(); 
     305                                } 
     306 
     307                                if ( nearestListBlock  ) 
     308                                { 
     309                                        var firstListItem = nearestListBlock.getFirst( function( node ) 
     310                                                { 
     311                                                        return node.type == CKEDITOR.NODE_ELEMENT && node.is( 'li' ); 
     312                                                }), 
     313                                                rangeStart = range.startContainer, 
     314                                                indentWholeList = firstListItem.equals( rangeStart ) || firstListItem.contains( rangeStart ); 
     315 
     316                                        // Indent the entire list if  cursor is inside the first list item. (#3893) 
     317                                        if ( !( indentWholeList && indentElement( nearestListBlock ) ) ) 
     318                                        indentList( nearestListBlock ); 
     319                                } 
     320                                else 
     321                                        indentBlock(); 
     322                        } 
     323 
     324                        // Clean up the markers. 
     325                        CKEDITOR.dom.element.clearAllMarkers( database ); 
     326 
    319327                        editor.forceNextSelectionCheck(); 
    320328                        selection.selectBookmarks( bookmarks ); 
  • CKEditor/branches/versions/3.4.x/_source/plugins/justify/plugin.js

    r5206 r5709  
    1 /* 
     1/* 
    22Copyright (c) 2003-2010, CKSource - Frederico Knabben. All rights reserved. 
    33For licensing, see LICENSE.html or http://ckeditor.com/license 
     
    7474 
    7575                        var bookmarks = selection.createBookmarks(), 
    76                                 ranges = selection.getRanges(); 
     76                                ranges = selection.getRanges( true ); 
    7777 
    7878 
  • CKEditor/branches/versions/3.4.x/_source/plugins/link/dialogs/link.js

    r5534 r5709  
    12951295                                // Create element if current selection is collapsed. 
    12961296                                var selection = editor.getSelection(), 
    1297                                         ranges = selection.getRanges(); 
     1297                                        ranges = selection.getRanges( true ); 
    12981298                                if ( ranges.length == 1 && ranges[0].collapsed ) 
    12991299                                { 
  • CKEditor/branches/versions/3.4.x/_source/plugins/link/plugin.js

    r5678 r5709  
    1 /* 
     1/* 
    22Copyright (c) 2003-2010, CKSource - Frederico Knabben. All rights reserved. 
    33For licensing, see LICENSE.html or http://ckeditor.com/license 
     
    111111                        editor.contextMenu.addListener( function( element, selection ) 
    112112                                { 
    113                                         if ( !element ) 
     113                                        if ( !element || element.isReadOnly() ) 
    114114                                                return null; 
    115115 
     
    178178        { 
    179179                var range; 
    180                 try { range  = editor.getSelection().getRanges()[ 0 ]; } 
     180                try 
     181                { 
     182                        range  = editor.getSelection().getRanges( true )[ 0 ]; 
     183                        range.shrink( CKEDITOR.SHRINK_TEXT ); 
     184                        var root = range.getCommonAncestor(); 
     185                        return root.getAscendant( 'a', true ); 
     186                } 
    181187                catch( e ) { return null; } 
    182  
    183                 range.shrink( CKEDITOR.SHRINK_TEXT ); 
    184                 var root = range.getCommonAncestor(); 
    185                 return root.getAscendant( 'a', true ); 
    186188        } 
    187189}; 
  • CKEditor/branches/versions/3.4.x/_source/plugins/list/plugin.js

    r5692 r5709  
    1 /* 
     1/* 
    22Copyright (c) 2003-2010, CKSource - Frederico Knabben. All rights reserved. 
    33For licensing, see LICENSE.html or http://ckeditor.com/license 
     
    401401                        var doc = editor.document, 
    402402                                selection = editor.getSelection(), 
    403                                 ranges = selection && selection.getRanges(); 
     403                                ranges = selection && selection.getRanges( true ); 
    404404 
    405405                        // There should be at least one selected range. 
     
    449449                        // or multiple lists have to be cancelled. 
    450450                        var listGroups = [], 
    451                                 database = {}; 
    452  
    453                         while ( ranges.length > 0 ) 
    454                         { 
    455                                 range = ranges.shift(); 
    456  
     451                                database = {}, 
     452                                rangeIterator = ranges.createIterator(), 
     453                                index = 0; 
     454 
     455                        while ( ( range = rangeIterator.getNextRange() ) && ++index ) 
     456                        { 
    457457                                var boundaryNodes = range.getBoundaryNodes(), 
    458458                                        startNode = boundaryNodes.startNode, 
     
    472472                                while ( ( block = iterator.getNextParagraph() ) ) 
    473473                                { 
     474                                        // Avoid duplicate blocks get processed across ranges. 
     475                                        if( block.getCustomData( 'list_block' ) ) 
     476                                                continue; 
     477                                        else 
     478                                                CKEDITOR.dom.element.setMarker( database, block, 'list_block', 1 ); 
     479 
    474480                                        var path = new CKEDITOR.dom.elementPath( block ), 
    475481                                                pathElements = path.elements, 
     
    491497                                                        // should belong to a different group of paragraphs before 
    492498                                                        // the list. (Bug #1309) 
    493                                                         blockLimit.removeCustomData( 'list_group_object' ); 
     499                                                        blockLimit.removeCustomData( 'list_group_object_' + index ); 
    494500 
    495501                                                        var groupObj = element.getCustomData( 'list_group_object' ); 
     
    510516                                                continue; 
    511517 
    512                                         // No list ancestor? Group by block limit. 
     518                                        // No list ancestor? Group by block limit, but don't mix contents from different ranges. 
    513519                                        var root = blockLimit; 
    514                                         if ( root.getCustomData( 'list_group_object' ) ) 
    515                                                 root.getCustomData( 'list_group_object' ).contents.push( block ); 
     520                                        if ( root.getCustomData( 'list_group_object_' + index ) ) 
     521                                                root.getCustomData( 'list_group_object_' + index ).contents.push( block ); 
    516522                                        else 
    517523                                        { 
    518524                                                groupObj = { root : root, contents : [ block ] }; 
    519                                                 CKEDITOR.dom.element.setMarker( database, root, 'list_group_object', groupObj ); 
     525                                                CKEDITOR.dom.element.setMarker( database, root, 'list_group_object_' + index, groupObj ); 
    520526                                                listGroups.push( groupObj ); 
    521527                                        } 
     
    551557                                                'getPrevious' : 'getNext' ]( CKEDITOR.dom.walker.whitespaces( true ) ); 
    552558                                        if ( sibling && sibling.getName && 
    553                                             sibling.getName() == listCommand.type ) 
     559                                                sibling.getName() == listCommand.type ) 
    554560                                        { 
    555561                                                sibling.remove(); 
  • CKEditor/branches/versions/3.4.x/_source/plugins/liststyle/plugin.js

    r5534 r5709  
    4343                                editor.contextMenu.addListener( function( element, selection ) 
    4444                                        { 
    45                                                 if ( !element ) 
     45                                                if ( !element || element.isReadOnly() ) 
    4646                                                        return null; 
    4747 
  • CKEditor/branches/versions/3.4.x/_source/plugins/pagebreak/plugin.js

    r5692 r5709  
    8383                breakObject = editor.createFakeElement( breakObject, 'cke_pagebreak', 'div' ); 
    8484 
    85                 var ranges = editor.getSelection().getRanges(); 
     85                var ranges = editor.getSelection().getRanges( true ); 
    8686 
    8787                editor.fire( 'saveSnapshot' ); 
    8888 
    89                 for ( var range, i = 0 ; i < ranges.length ; i++ ) 
     89                for ( var range, i = ranges.length - 1 ; i >= 0; i-- ) 
    9090                { 
    9191                        range = ranges[ i ]; 
    9292 
    93                         if ( i > 0 ) 
     93                        if ( i < ranges.length -1 ) 
    9494                                breakObject = breakObject.clone( true ); 
    9595 
  • CKEditor/branches/versions/3.4.x/_source/plugins/removeformat/plugin.js

    r5460 r5709  
    1 /* 
     1/* 
    22Copyright (c) 2003-2010, CKSource - Frederico Knabben. All rights reserved. 
    33For licensing, see LICENSE.html or http://ckeditor.com/license 
     
    3636 
    3737                                var filter = CKEDITOR.plugins.removeformat.filter; 
    38                                 var ranges = editor.getSelection().getRanges(); 
     38                                var ranges = editor.getSelection().getRanges( true ), 
     39                                        iterator = ranges.createIterator(), 
     40                                        range; 
    3941 
    40                                 for ( var i = 0, range ; range = ranges[ i ] ; i++ ) 
     42                                while ( range = iterator.getNextRange() ) 
    4143                                { 
    4244                                        if ( range.collapsed ) 
  • CKEditor/branches/versions/3.4.x/_source/plugins/scayt/plugin.js

    r5656 r5709  
    625625                        if ( editor.contextMenu && editor.addMenuItems ) 
    626626                        { 
    627                                 editor.contextMenu.addListener( function(  ) 
    628                                         { 
    629                                                 if ( !plugin.isScaytEnabled( editor ) ) 
     627                                editor.contextMenu.addListener( function( element, selection ) 
     628                                        { 
     629                                                if ( !plugin.isScaytEnabled( editor ) 
     630                                                                || selection.getCommonAncestor().isReadOnly() ) 
    630631                                                        return null; 
    631632 
  • CKEditor/branches/versions/3.4.x/_source/plugins/selection/plugin.js

    r5692 r5709  
    1 /* 
     1/* 
    22Copyright (c) 2003-2010, CKSource - Frederico Knabben. All rights reserved. 
    33For licensing, see LICENSE.html or http://ckeditor.com/license 
     
    485485                 * alert(ranges.length); 
    486486                 */ 
    487                 getRanges : 
    488                         CKEDITOR.env.ie ? 
     487                getRanges : (function () 
     488                { 
     489                        var func = CKEDITOR.env.ie ? 
    489490                                ( function() 
    490491                                { 
     
    574575                                        return function() 
    575576                                        { 
    576                                                 var cache = this._.cache; 
    577                                                 if ( cache.ranges ) 
    578                                                         return cache.ranges; 
    579  
    580577                                                // IE doesn't have range support (in the W3C way), so we 
    581578                                                // need to do some magic to transform selections into 
     
    600597                                                        range.setEnd( new CKEDITOR.dom.node( boundaryInfo.container ), boundaryInfo.offset ); 
    601598 
    602                                                         return ( cache.ranges = [ range ] ); 
     599                                                        return [ range ]; 
    603600                                                } 
    604601                                                else if ( type == CKEDITOR.SELECTION_ELEMENT ) 
    605602                                                { 
    606                                                         var retval = this._.cache.ranges = []; 
     603                                                        var retval = []; 
    607604 
    608605                                                        for ( var i = 0 ; i < nativeRange.length ; i++ ) 
     
    625622                                                } 
    626623 
    627                                                 return ( cache.ranges = [] ); 
     624                                                return []; 
    628625                                        }; 
    629626                                })() 
     
    631628                                function() 
    632629                                { 
    633                                         var cache = this._.cache; 
    634                                         if ( cache.ranges ) 
    635                                                 return cache.ranges; 
    636630 
    637631                                        // On browsers implementing the W3C range, we simply 
     
    654648                                                ranges.push( range ); 
    655649                                        } 
    656  
    657                                         return ( cache.ranges = ranges ); 
    658                                 }, 
     650                                        return ranges; 
     651                                }; 
     652 
     653                        return function( onlyEditables ) 
     654                        { 
     655                                var cache = this._.cache; 
     656                                if ( cache.ranges && !onlyEditables ) 
     657                                        return cache.ranges; 
     658                                else if ( !cache.ranges ) 
     659                                        cache.ranges = new CKEDITOR.dom.rangeList( func.call( this ) ); 
     660 
     661                                // Split range into multiple by read-only nodes. 
     662                                if ( onlyEditables ) 
     663                                { 
     664                                        var ranges = cache.ranges; 
     665                                        for ( var i = 0; i < ranges.length; i++ ) 
     666                                        { 
     667                                                var range = ranges[ i ]; 
     668 
     669                                                // Drop range spans inside one ready-only node. 
     670                                                var parent = range.getCommonAncestor(); 
     671                                                if ( parent.isReadOnly()) 
     672                                                        ranges.splice( i, 1 ); 
     673 
     674                                                if ( range.collapsed ) 
     675                                                        continue; 
     676 
     677                                                var startContainer = range.startContainer, 
     678                                                        endContainer = range.endContainer, 
     679                                                        startOffset = range.startOffset, 
     680                                                        endOffset = range.endOffset, 
     681                                                        walkerRange = range.clone(); 
     682 
     683                                                // Range may start inside a non-editable element, restart range 
     684                                                // by the end of it. 
     685                                                var readOnly; 
     686                                                if ( readOnly = startContainer.isReadOnly() ) 
     687                                                        range.setStartAfter( readOnly ); 
     688 
     689                                                // Enlarge range start/end with text node to avoid walker 
     690                                                // being DOM destructive, it doesn't interfere our checking 
     691                                                // of elements below as well. 
     692                                                if ( startContainer && startContainer.type == CKEDITOR.NODE_TEXT ) 
     693                                                { 
     694                                                        if ( startOffset >= startContainer.getLength() ) 
     695                                                                walkerRange.setStartAfter( startContainer ); 
     696                                                        else 
     697                                                                walkerRange.setStartBefore( startContainer ); 
     698                                                } 
     699 
     700                                                if ( endContainer && endContainer.type == CKEDITOR.NODE_TEXT ) 
     701                                                { 
     702                                                        if ( !endOffset ) 
     703                                                                walkerRange.setEndBefore( endContainer ); 
     704                                                        else 
     705                                                                walkerRange.setEndAfter( endContainer ); 
     706                                                } 
     707 
     708                                                // Looking for non-editable element inside the range. 
     709                                                var walker = new CKEDITOR.dom.walker( walkerRange ); 
     710                                                walker.evaluator = function( node ) 
     711                                                { 
     712                                                        if ( node.type == CKEDITOR.NODE_ELEMENT 
     713                                                                && node.getAttribute( 'contenteditable' ) == 'false' ) 
     714                                                        { 
     715                                                                var newRange = range.clone(); 
     716                                                                range.setEndBefore( node ); 
     717 
     718                                                                // Drop collapsed range around read-only elements, 
     719                                                                // it make sure the range list empty when selecting 
     720                                                                // only non-editable elements. 
     721                                                                if ( range.collapsed ) 
     722                                                                        ranges.splice( i--, 1 ); 
     723                                                                 
     724                                                                // Avoid creating invalid range. 
     725                                                                if ( !( node.getPosition( walkerRange.endContainer ) & CKEDITOR.POSITION_CONTAINS ) ) 
     726                                                                { 
     727                                                                        newRange.setStartAfter( node ); 
     728                                                                        if ( !newRange.collapsed ) 
     729                                                                                ranges.splice( i + 1, 0, newRange ); 
     730                                                                } 
     731 
     732                                                                return true; 
     733                                                        } 
     734 
     735                                                        return false; 
     736                                                }; 
     737 
     738                                                walker.next(); 
     739                                        } 
     740                                } 
     741 
     742                                return cache.ranges; 
     743                        } 
     744                })(), 
    659745 
    660746                /** 
     
    860946                                this._.cache.selectedElement = element; 
    861947                                this._.cache.startElement = element; 
    862                                 this._.cache.ranges = [ range ]; 
     948                                this._.cache.ranges = new CKEDITOR.dom.rangeList( range ); 
    863949                                this._.cache.type = CKEDITOR.SELECTION_ELEMENT; 
    864950 
     
    9171003                                this._.cache.selectedElement = null; 
    9181004                                this._.cache.startElement = ranges[ 0 ].getTouchedStartNode(); 
    919                                 this._.cache.ranges = ranges; 
     1005                                this._.cache.ranges = new CKEDITOR.dom.rangeList( ranges ); 
    9201006                                this._.cache.type = CKEDITOR.SELECTION_TEXT; 
    9211007 
     
    9251011                        if ( CKEDITOR.env.ie ) 
    9261012                        { 
    927                                 // IE doesn't accept multiple ranges selection, so we just 
    928                                 // select the first one. 
     1013                                if ( ranges.length > 1 ) 
     1014                                { 
     1015                                        // IE doesn't accept multiple ranges selection, so we join all into one. 
     1016                                        var last = ranges[ ranges.length -1 ] ; 
     1017                                        ranges[ 0 ].setEnd( last.endContainer, last.endOffset ); 
     1018                                        ranges.length = 1; 
     1019                                } 
     1020 
    9291021                                if ( ranges[ 0 ] ) 
    9301022                                        ranges[ 0 ].select(); 
     
    9351027                        { 
    9361028                                var sel = this.getNative(); 
    937                                 sel.removeAllRanges(); 
     1029 
     1030                                if ( ranges.length ) 
     1031                                        sel.removeAllRanges(); 
    9381032 
    9391033                                for ( var i = 0 ; i < ranges.length ; i++ ) 
    9401034                                { 
     1035                                        // Joining sequential ranges introduced by 
     1036                                        // readonly elements protection. 
     1037                                        if ( i < ranges.length -1 ) 
     1038                                        { 
     1039                                                var left = ranges[ i ], right = ranges[ i +1 ], 
     1040                                                                between = left.clone(); 
     1041                                                between.setStart( left.endContainer, left.endOffset ); 
     1042                                                between.setEnd( right.startContainer, right.startOffset ); 
     1043 
     1044                                                // Don't confused by Firefox adjancent multi-ranges 
     1045                                                // introduced by table cells selection. 
     1046                                                if ( !between.collapsed ) 
     1047                                                { 
     1048                                                        between.shrink( CKEDITOR.NODE_ELEMENT, true ); 
     1049                                                        if ( between.getCommonAncestor().isReadOnly()) 
     1050                                                        { 
     1051                                                                right.setStart( left.startContainer, left.startOffset ); 
     1052                                                                ranges.splice( i--, 1 ); 
     1053                                                                continue; 
     1054                                                        } 
     1055                                                } 
     1056                                        } 
     1057 
    9411058                                        var range = ranges[ i ]; 
    9421059                                        var nativeRange = this.document.$.createRange(); 
     
    9731090                createBookmarks : function( serializable ) 
    9741091                { 
    975                         var retval = [], 
    976                                 ranges = this.getRanges(), 
    977                                 length = ranges.length, 
    978                                 bookmark; 
    979                         for ( var i = 0; i < length ; i++ ) 
    980                         { 
    981                             retval.push( bookmark = ranges[ i ].createBookmark( serializable, true ) ); 
    982  
    983                                 serializable = bookmark.serializable; 
    984  
    985                                 var bookmarkStart = serializable ? this.document.getById( bookmark.startNode ) : bookmark.startNode, 
    986                                         bookmarkEnd = serializable ? this.document.getById( bookmark.endNode ) : bookmark.endNode; 
    987  
    988                             // Updating the offset values for rest of ranges which have been mangled(#3256). 
    989                             for ( var j = i + 1 ; j < length ; j++ ) 
    990                             { 
    991                                 var dirtyRange = ranges[ j ], 
    992                                        rangeStart = dirtyRange.startContainer, 
    993                                        rangeEnd = dirtyRange.endContainer; 
    994  
    995                                rangeStart.equals( bookmarkStart.getParent() ) && dirtyRange.startOffset++; 
    996                                rangeStart.equals( bookmarkEnd.getParent() ) && dirtyRange.startOffset++; 
    997                                rangeEnd.equals( bookmarkStart.getParent() ) && dirtyRange.endOffset++; 
    998                                rangeEnd.equals( bookmarkEnd.getParent() ) && dirtyRange.endOffset++; 
    999                             } 
    1000                         } 
    1001  
    1002                         return retval; 
     1092                        return this.getRanges().createBookmarks( serializable ); 
    10031093                }, 
    10041094 
     
    10111101                createBookmarks2 : function( normalized ) 
    10121102                { 
    1013                         var bookmarks = [], 
    1014                                 ranges = this.getRanges(); 
    1015  
    1016                         for ( var i = 0 ; i < ranges.length ; i++ ) 
    1017                                 bookmarks.push( ranges[i].createBookmark2( normalized ) ); 
    1018  
    1019                         return bookmarks; 
     1103                        return this.getRanges().createBookmarks2( normalized ); 
    10201104                }, 
    10211105 
  • CKEditor/branches/versions/3.4.x/_source/plugins/showborders/plugin.js

  • CKEditor/branches/versions/3.4.x/_source/plugins/specialchar/dialogs/specialchar.js

    r5504 r5709  
    1 /* 
     1/* 
    22Copyright (c) 2003-2010, CKSource - Frederico Knabben. All rights reserved. 
    33For licensing, see LICENSE.html or http://ckeditor.com/license 
     
    1616        { 
    1717                var selection = editor.getSelection(), 
    18                         ranges    = selection.getRanges(), 
     18                        ranges = selection.getRanges( true ), 
    1919                        range, textNode; 
    2020 
    2121                editor.fire( 'saveSnapshot' ); 
    2222 
    23                 for ( var i = 0, len = ranges.length ; i < len ; i++ ) 
     23                for ( var i = ranges.length - 1; i >= 0 ; i-- ) 
    2424                { 
    2525                        range = ranges[ i ]; 
    2626                        range.deleteContents(); 
    2727 
    28                         textNode =  CKEDITOR.dom.element.createFromHtml( specialChar ); 
     28                        textNode = CKEDITOR.dom.element.createFromHtml( specialChar ); 
    2929                        range.insertNode( textNode ); 
    3030                } 
  • CKEditor/branches/versions/3.4.x/_source/plugins/styles/plugin.js

    r5656 r5709  
    377377                var dtd = CKEDITOR.dtd[ elementName ] || ( isUnknownElement = true, CKEDITOR.dtd.span ); 
    378378 
    379                 // Bookmark the range so we can re-select it after processing. 
    380                 var bookmark = range.createBookmark(); 
    381  
    382379                // Expand the range. 
    383380                range.enlarge( CKEDITOR.ENLARGE_ELEMENT ); 
     
    547544                firstNode.remove(); 
    548545                lastNode.remove(); 
    549                 range.moveToBookmark( bookmark ); 
     546 
    550547                // Minimize the result range to exclude empty text nodes. (#5374) 
    551548                range.shrink( CKEDITOR.SHRINK_TEXT ); 
     
    12751272        function applyStyle( document, remove ) 
    12761273        { 
    1277                 // Get all ranges from the selection. 
    1278                 var selection = document.getSelection(); 
    1279                 var ranges = selection.getRanges(); 
    1280                 var func = remove ? this.removeFromRange : this.applyToRange; 
    1281  
    1282                 // Apply the style to the ranges. 
    1283                 for ( var i = 0 ; i < ranges.length ; i++ ) 
    1284                         func.call( this, ranges[ i ] ); 
    1285  
    1286                 // Select the ranges again. 
    1287                 selection.selectRanges( ranges ); 
     1274                var selection = document.getSelection(), 
     1275                        // Bookmark the range so we can re-select it after processing. 
     1276                        bookmarks = selection.createBookmarks(), 
     1277                        ranges = selection.getRanges( true ), 
     1278                        func = remove ? this.removeFromRange : this.applyToRange, 
     1279                        range; 
     1280 
     1281                var iterator = ranges.createIterator(); 
     1282                while ( range = iterator.getNextRange() ) 
     1283                        func.call( this, range ); 
     1284 
     1285                selection.selectBookmarks( bookmarks ); 
    12881286        } 
    12891287})(); 
  • CKEditor/branches/versions/3.4.x/_source/plugins/table/plugin.js

    r5548 r5709  
    1 /* 
     1/* 
    22Copyright (c) 2003-2010, CKSource - Frederico Knabben. All rights reserved. 
    33For licensing, see LICENSE.html or http://ckeditor.com/license 
     
    5959                        editor.contextMenu.addListener( function( element, selection ) 
    6060                                { 
    61                                         if ( !element ) 
     61                                        if ( !element || element.isReadOnly()) 
    6262                                                return null; 
    6363 
  • CKEditor/branches/versions/3.4.x/_source/plugins/tabletools/plugin.js

    r5572 r5709  
    1 /* 
     1/* 
    22Copyright (c) 2003-2010, CKSource - Frederico Knabben. All rights reserved. 
    33For licensing, see LICENSE.html or http://ckeditor.com/license 
     
    10441044                                editor.contextMenu.addListener( function( element, selection ) 
    10451045                                        { 
    1046                                                 if ( !element ) 
     1046                                                if ( !element || element.isReadOnly() ) 
    10471047                                                        return null; 
    10481048 
  • CKEditor/branches/versions/3.4.x/_source/plugins/wysiwygarea/plugin.js

    r5692 r5709  
    1616        // Matching an empty paragraph at the end of document. 
    1717        var emptyParagraphRegexp = /\s*<(p|div|address|h\d|center|li)[^>]*>\s*(?:<br[^>]*>|&nbsp;|\u00A0|&#160;)?\s*(:?<\/\1>)?\s*(?=$|<\/body>)/gi; 
     18 
     19        function checkReadOnly( selection ) 
     20        { 
     21                return selection.getCommonAncestor().isReadOnly(); 
     22        } 
    1823 
    1924        function onInsertHtml( evt ) 
     
    2227                { 
    2328                        this.focus(); 
     29 
     30                        var selection = this.getSelection(); 
     31                        if ( checkReadOnly( selection ) ) 
     32                                return; 
     33 
     34                        var data = evt.data 
    2435                        this.fire( 'saveSnapshot' ); 
    2536 
    26                         var selection = this.getSelection(), 
    27                                 data = evt.data; 
    2837 
    2938                        if ( this.dataProcessor ) 
     
    6069                { 
    6170                        this.focus(); 
     71 
     72                        var selection = this.getSelection(); 
     73                        if ( checkReadOnly( selection ) ) 
     74                                return; 
     75 
    6276                        this.fire( 'saveSnapshot' ); 
    6377 
    64                         var element = evt.data, 
     78                        var ranges = selection.getRanges(), 
     79                                element = evt.data, 
    6580                                elementName = element.getName(), 
    6681                                isBlock = CKEDITOR.dtd.$block[ elementName ]; 
    67  
    68                         var selection = this.getSelection(), 
    69                                 ranges = selection.getRanges(); 
    7082 
    7183                        var selIsLocked = selection.isLocked; 
     
    222234                                if ( previousElement && previousElement.getName 
    223235                                         && !( previousElement.getName() in nonExitableElementNames ) 
    224                                          && isBlankParagraph( previousElement ) 
    225                                          && range.moveToElementEditStart( previousElement ) 
    226236                                         || nextElement && nextElement.getName 
    227                                                 && !( nextElement.getName() in nonExitableElementNames ) 
    228                                                 && isBlankParagraph( nextElement ) 
    229                                                 && range.moveToElementEditStart( nextElement ) ) 
     237                                                && !( nextElement.getName() in nonExitableElementNames ) ) 
    230238                                { 
    231                                         fixedBlock.remove(); 
     239                                        if ( isBlankParagraph( previousElement ) && range.moveToElementEditStart( previousElement ) 
     240                                                        || isBlankParagraph( nextElement ) && range.moveToElementEditStart( nextElement ) ) 
     241                                                fixedBlock.remove(); 
     242 
     243                                        // Firefox prefer to anchor cursor after non-editable elements 
     244                                        // when navigate to them, leaving native behavior untouched. (#5834) 
     245                                        if ( CKEDITOR.env.gecko && ( previousElement.isReadOnly() || nextElement.isReadOnly() ) ) 
     246                                        { 
     247                                                range.moveToPosition( fixedBlock, CKEDITOR.POSITION_BEFORE_START ); 
     248                                                fixedBlock.remove(); 
     249                                        } 
    232250                                } 
    233251                        } 
  • CKEditor/branches/versions/3.4.x/ckeditor.pack

    r5606 r5709  
    1 /* 
     1/* 
    22 * CKPackager - Sample Package file 
    33 */ 
     
    130130                                        '_source/core/dom/walker.js', 
    131131                                        '_source/core/dom/range.js', 
     132                                        '_source/core/dom/rangelist.js', 
    132133                                        '_source/core/_bootstrap.js', 
    133134                                        '_source/skins/kama/skin.js', 
  • CKEditor/branches/versions/3.4.x/config.js

    r5206 r5709  
    1 /* 
     1/* 
    22Copyright (c) 2003-2010, CKSource - Frederico Knabben. All rights reserved. 
    33For licensing, see LICENSE.html or http://ckeditor.com/license 
Note: See TracChangeset for help on using the changeset viewer.
© 2003 – 2012 CKSource – Frederico Knabben. All rights reserved. | Terms of use | Privacy policy