Ticket #4513: 4513_3.patch

File 4513_3.patch, 7.2 KB (added by Garry Yao, 9 years ago)
  • _source/plugins/link/dialogs/link.js

     
    55
    66CKEDITOR.dialog.add( 'link', function( editor )
    77{
     8        var plugin = CKEDITOR.plugins.link;
    89        // Handles the event when the "Target" selection box is changed.
    910        var targetChanged = function()
    1011        {
     
    9394
    9495        var parseLink = function( editor, element )
    9596        {
    96                 var href = element ? ( element.getAttribute( '_cke_saved_href' ) || element.getAttribute( 'href' ) ) : '',
     97                var href = ( element  && ( element.getAttribute( '_cke_saved_href' ) || element.getAttribute( 'href' ) ) ) || '',
    9798                        javascriptMatch,
    9899                        emailMatch,
    99100                        anchorMatch,
     
    11301131
    11311132                        var editor = this.getParentEditor(),
    11321133                                selection = editor.getSelection(),
    1133                                 ranges = selection.getRanges(),
    1134                                 element = null,
    1135                                 me = this;
    1136                         // Fill in all the relevant fields if there's already one link selected.
    1137                         if ( ranges.length == 1 )
    1138                         {
     1134                                element = null;
    11391135
    1140                                 var rangeRoot = ranges[0].getCommonAncestor( true );
    1141                                 element = rangeRoot.getAscendant( 'a', true );
    1142                                 if ( element && element.getAttribute( 'href' ) )
    1143                                 {
    1144                                         selection.selectElement( element );
    1145                                 }
    1146                                 else if ( ( element = rangeRoot.getAscendant( 'img', true ) ) &&
    1147                                                  element.getAttribute( '_cke_real_element_type' ) &&
    1148                                                  element.getAttribute( '_cke_real_element_type' ) == 'anchor' )
    1149                                 {
    1150                                         this.fakeObj = element;
    1151                                         element = editor.restoreRealElement( this.fakeObj );
    1152                                         selection.selectElement( this.fakeObj );
    1153                                 }
    1154                                 else
    1155                                         element = null;
    1156                         }
     1136                        // Fill in all the relevant fields if there's already one link selected.
     1137                        if ( ( element = plugin.getSelectedLink( editor ) ) && element.hasAttribute( 'href' ) )
     1138                                selection.selectElement( element );
     1139                        else if ( ( element = selection.getSelectedElement() ) && element.is( 'img' )
     1140                                        && element.getAttribute( '_cke_real_element_type' )
     1141                                        && element.getAttribute( '_cke_real_element_type' ) == 'anchor' )
     1142                        {
     1143                                this.fakeObj = element;
     1144                                element = editor.restoreRealElement( this.fakeObj );
     1145                                selection.selectElement( this.fakeObj );
     1146                        }
     1147                        else
     1148                                element = null;
    11571149
    11581150                        this.setupContent( parseLink.apply( this, [ editor, element ] ) );
    11591151                },
  • _source/plugins/link/plugin.js

     
    107107
    108108                                        if ( !isAnchor )
    109109                                        {
    110                                                 if ( !( element = element.getAscendant( 'a', true ) ) )
     110                                                if ( !( element = CKEDITOR.plugins.link.getSelectedLink( editor ) ) )
    111111                                                        return null;
    112112
    113113                                                isAnchor = ( element.getAttribute( 'name' ) && !element.getAttribute( 'href' ) );
     
    147147        requires : [ 'fakeobjects' ]
    148148} );
    149149
     150CKEDITOR.plugins.link =
     151{
     152        /**
     153         *  Get the surrounding link element of current selection.
     154         * @param editor
     155         * @example CKEDITOR.plugins.link.getSelectedLink( editor );
     156         * The following selection will all return the link element.   
     157         *       <pre>
     158         *  <a href="#">li^nk</a>
     159         *  <a href="#">[link]</a>
     160         *  text[<a href="#">link]</a>
     161         *  <a href="#">li[nk</a>]
     162         *  [<b><a href="#">li]nk</a></b>]
     163         *  [<a href="#"><b>li]nk</b></a>
     164         * </pre>
     165         */
     166        getSelectedLink : function( editor )
     167        {
     168                var range;
     169                try { range  = editor.getSelection().getRanges()[ 0 ]; }
     170                catch( e ) { return null; }
     171
     172                range.shrink();
     173                var root = range.getCommonAncestor();
     174                return root.getAscendant( 'a', true );
     175        }
     176
     177};
     178
    150179CKEDITOR.unlinkCommand = function(){};
    151180CKEDITOR.unlinkCommand.prototype =
    152181{
  • _source/core/dom/range.js

     
    12351235                },
    12361236
    12371237                /**
     1238                 *  Descrease the range to make sure that boundaries
     1239                 *  always anchor beside text nodes.
     1240                 */
     1241                shrink : function()
     1242                {
     1243                        // Unable to shrink a collapsed range.
     1244                        if( this.collapsed )
     1245                                return false;
     1246                        else
     1247                        {
     1248                                var walkerRange = this.clone();
     1249
     1250                                var startContainer = this.startContainer,
     1251                                        endContainer = this.endContainer,
     1252                                        startOffset = this.startOffset,
     1253                                        endOffset = this.endOffset,
     1254                                        collapsed = this.collapsed;
     1255
     1256                                // Whether the start/end boundary is moveable.
     1257                                var moveStart = 1,
     1258                                                moveEnd = 1;
     1259
     1260                                if ( startContainer && startContainer.type == CKEDITOR.NODE_TEXT )
     1261                                {
     1262                                        if ( !startOffset )
     1263                                                walkerRange.setStartBefore( startContainer );
     1264                                        else if ( startOffset >= startContainer.getLength( ) )
     1265                                                walkerRange.setStartAfter( startContainer );
     1266                                        else
     1267                                        {
     1268                                                // Enlarge the range properly to avoid walker making
     1269                                                // DOM changes caused by triming the text nodes later.
     1270                                                walkerRange.setStartBefore( startContainer );
     1271                                                moveStart = 0;
     1272                                        }
     1273                                }
     1274                               
     1275                                if ( endContainer && endContainer.type == CKEDITOR.NODE_TEXT )
     1276                                {
     1277                                        if ( !endOffset )
     1278                                                walkerRange.setEndBefore( endContainer );
     1279                                        else if ( endOffset >= endContainer.getLength( ) )
     1280                                                walkerRange.setEndAfter( endContainer );
     1281                                        else
     1282                                        {
     1283                                                walkerRange.setEndAfter( endContainer );
     1284                                                moveEnd = 0;
     1285                                        }
     1286                                }
     1287
     1288                                var walker = new CKEDITOR.dom.walker( walkerRange );
     1289                                walker.evaluator = function( node )
     1290                                {
     1291                                        return node.type == CKEDITOR.NODE_TEXT;
     1292                                };
     1293
     1294                                var currentElement;
     1295                                walker.guard = function( node, movingOut )
     1296                                {
     1297                                        // Stop when we've walked "through" an element.
     1298                                        if( movingOut && node.equals( currentElement ) )
     1299                                                return false;
     1300
     1301                                        if( !movingOut && node.type == CKEDITOR.NODE_ELEMENT )
     1302                                                currentElement = node;
     1303                                };
     1304
     1305                                if( moveStart )
     1306                                {
     1307                                        var textStart = walker.next();
     1308                                        textStart && this.setStartBefore( textStart );
     1309                                }
     1310
     1311                                if( moveEnd )
     1312                                {
     1313                                        walker.reset();
     1314                                        var textEnd = walker.previous();
     1315                                        textEnd && this.setEndAfter( textEnd );
     1316                                }
     1317                               
     1318                                return !!( moveStart || moveEnd );
     1319                        }
     1320                },
     1321
     1322                /**
    12381323                 * Inserts a node at the start of the range. The range will be expanded
    12391324                 * the contain the node.
    12401325                 */
  • _source/core/dom/walker.js

     
    101101                                                node = null;
    102102                                }
    103103                                else
    104                                         node = ( guard ( node ) === false ) ?
     104                                        node = ( guard ( node, true ) === false ) ?
    105105                                                null : node.getPreviousSourceNode( true, type, guard );
    106106                        }
    107107                        else
     
    115115                                                node = null;
    116116                                }
    117117                                else
    118                                         node = ( guard ( range.startContainer ) === false ) ?
     118                                        node = ( guard ( range.startContainer, true ) === false ) ?
    119119                                                null : range.startContainer.getNextSourceNode( true, type, guard ) ;
    120120                        }
    121121                }
© 2003 – 2019 CKSource – Frederico Knabben. All rights reserved. | Terms of use | Privacy policy