Ticket #3582: 3582_14.patch

File 3582_14.patch, 22.4 KB (added by garry.yao, 13 months ago)
  • _source/core/dom/element.js

     
    429429                                                        name = 'className'; 
    430430                                                        break; 
    431431 
     432                                                case 'name': 
     433                                                        return this.$.name; 
     434 
    432435                                                case 'tabindex': 
    433436                                                        var tabIndex = standard.call( this, name ); 
    434437 
     
    884887                 * @param {String} name The attribute name. 
    885888                 * @example 
    886889                 */ 
    887                 hasAttribute : function( name ) 
     890                hasAttribute : (function() 
    888891                { 
    889                         var $attr = this.$.attributes.getNamedItem( name ); 
    890                         return !!( $attr && $attr.specified ); 
    891                 }, 
    892  
     892                        function standard( name ) 
     893                        { 
     894                                var $attr = this.$.attributes.getNamedItem( name ); 
     895                                return !!( $attr && $attr.specified ); 
     896                        } 
     897                         
     898                        return ( CKEDITOR.env.ie && CKEDITOR.env.version < 8 ) ?  
     899                                        function( name ) 
     900                                        { 
     901                                                // On IE < 8 the name attribute cannot be retrieved 
     902                                                // right after the element creation and setting the 
     903                                                // name with setAttribute. 
     904                                                if ( name == 'name' ) 
     905                                                        return !!this.$.name; 
     906 
     907                                                return standard.call( this, name ); 
     908                                        } 
     909                                : 
     910                                        standard; 
     911                })(), 
     912 
    893913                /** 
    894914                 * Hides this element (display:none). 
    895915                 * @example 
  • _source/plugins/forms/plugin.js

     
    261261 
    262262if ( CKEDITOR.env.ie ) 
    263263{ 
    264         CKEDITOR.dom.element.prototype.hasAttribute = function( name ) 
    265         { 
    266                 var $attr = this.$.attributes.getNamedItem( name ); 
     264        CKEDITOR.dom.element.prototype.hasAttribute = CKEDITOR.tools.override( CKEDITOR.dom.element.prototype.hasAttribute, 
     265                function( original ) 
     266                { 
     267                        return function( name ) 
     268                                { 
     269                                        var $attr = this.$.attributes.getNamedItem( name ); 
    267270 
    268                 if ( this.getName() == 'input' ) 
    269                 { 
    270                         switch ( name ) 
    271                         { 
    272                                 case 'class' : 
    273                                         return this.$.className.length > 0; 
    274                                 case 'checked' : 
    275                                         return !!this.$.checked; 
    276                                 case 'value' : 
    277                                         var type = this.getAttribute( 'type' ); 
    278                                         return type == 'checkbox' || type == 'radio' ? this.$.value != 'on' : this.$.value; 
    279                         } 
    280                 } 
     271                                        if ( this.getName() == 'input' ) 
     272                                        { 
     273                                                switch ( name ) 
     274                                                { 
     275                                                        case 'class' : 
     276                                                                return this.$.className.length > 0; 
     277                                                        case 'checked' : 
     278                                                                return !!this.$.checked; 
     279                                                        case 'value' : 
     280                                                                var type = this.getAttribute( 'type' ); 
     281                                                                return type == 'checkbox' || type == 'radio' ? this.$.value != 'on' : this.$.value; 
     282                                                } 
     283                                        } 
    281284 
    282                 return !!( $attr && $attr.specified ); 
    283         }; 
     285                                        return original.apply( this, arguments ); 
     286                                }; 
     287                }); 
    284288} 
  • _source/plugins/link/dialogs/anchor.js

     
    66CKEDITOR.dialog.add( 'anchor', function( editor ) 
    77{ 
    88        // Function called in onShow to load selected element. 
    9         var loadElements = function( editor, selection, element ) 
     9        var loadElements = function( element ) 
    1010        { 
    11                 this.editMode = true; 
    12                 this.editObj = element; 
     11                this._.selectedElement = element; 
    1312 
    14                 var attributeValue = this.editObj.getAttribute( 'name' ); 
    15                 if ( attributeValue ) 
    16                         this.setValueOf( 'info','txtName', attributeValue ); 
    17                 else 
    18                         this.setValueOf( 'info','txtName', "" ); 
     13                var attributeValue = element.data( 'cke-saved-name' ); 
     14                this.setValueOf( 'info','txtName', attributeValue || '' ); 
    1915        }; 
    2016 
     17        function createFakeAnchor( editor, anchor ) 
     18        { 
     19                return editor.createFakeElement( anchor, 'cke_anchor', 'anchor' ); 
     20        } 
     21 
    2122        return { 
    2223                title : editor.lang.anchor.title, 
    2324                minWidth : 300, 
    2425                minHeight : 60, 
    2526                onOk : function() 
    2627                { 
    27                         // Always create a new anchor, because of IE BUG. 
    28                         var name = this.getValueOf( 'info', 'txtName' ), 
    29                                 element = CKEDITOR.env.ie && !( CKEDITOR.document.$.documentMode >= 8 ) ? 
    30                                 editor.document.createElement( '<a name="' + CKEDITOR.tools.htmlEncode( name ) + '">' ) : 
    31                                 editor.document.createElement( 'a' ); 
     28                        var name = this.getValueOf( 'info', 'txtName' ); 
     29                        var attributes = 
     30                        { 
     31                                name : name, 
     32                                'data-cke-saved-name' : name 
     33                        }; 
    3234 
    33                         // Move contents and attributes of old anchor to new anchor. 
    34                         if ( this.editMode ) 
     35                        if ( this._.selectedElement ) 
    3536                        { 
    36                                 this.editObj.copyAttributes( element, { name : 1 } ); 
    37                                 this.editObj.moveChildren( element ); 
    38                         } 
     37                                if ( this._.selectedElement.data( 'cke-realelement' ) ) 
     38                                { 
     39                                        var newFake = createFakeAnchor( editor, editor.document.createElement( 'a', { attributes: attributes } ) ); 
     40                                        newFake.replace( this._.selectedElement ); 
     41                                } 
     42                                else 
     43                                        this._.selectedElement.setAttributes( attributes ); 
     44                        } 
     45                        else 
     46                        { 
     47                                var sel = editor.getSelection(), 
     48                                                range = sel && sel.getRanges()[ 0 ]; 
    3949 
    40                         // Set name. 
    41                         element.data( 'cke-saved-name', false ); 
    42                         element.setAttribute( 'name', name ); 
     50                                // Empty anchor 
     51                                if ( range.collapsed ) 
     52                                { 
     53                                        if ( CKEDITOR.env.ie && CKEDITOR.env.version < 9 ) 
     54                                                attributes['class'] = 'cke_anchor_empty'; 
    4355 
    44                         // Insert a new anchor. 
    45                         var fakeElement = editor.createFakeElement( element, 'cke_anchor', 'anchor' ); 
    46                         if ( !this.editMode ) 
    47                                 editor.insertElement( fakeElement ); 
    48                         else 
    49                         { 
    50                                 fakeElement.replace( this.fakeObj ); 
    51                                 editor.getSelection().selectElement( fakeElement ); 
    52                         } 
     56                                        if ( CKEDITOR.env.ie && CKEDITOR.env.version < 8 ) 
     57                                        { 
     58                                                attributes[ 'contenteditable' ] = 'false'; 
     59                                                attributes[ 'data-cke-editable' ] = 1; 
     60                                        } 
     61 
     62                                        var anchor = editor.document.createElement( 'a', { attributes: attributes } ); 
     63 
     64                                        // Transform the anchor into a fake element for browsers that need it. 
     65                                        if ( CKEDITOR.plugins.link.fakeAnchor ) 
     66                                                anchor = createFakeAnchor( editor, anchor ); 
     67 
     68                                        range.insertNode( anchor ); 
     69                                } 
     70                                else 
     71                                { 
     72                                        if ( CKEDITOR.env.ie && CKEDITOR.env.version < 9 ) 
     73                                                attributes['class'] = 'cke_anchor'; 
     74 
     75                                        // Apply style. 
     76                                        var style = new CKEDITOR.style( { element : 'a', attributes : attributes } ); 
     77                                        style.type = CKEDITOR.STYLE_INLINE; 
     78                                        style.apply( editor.document ); 
     79                                } 
     80                        } 
     81                }, 
    5382 
    54                         return true; 
     83                onHide : function() 
     84                { 
     85                        delete this._.selectedElement; 
    5586                }, 
     87 
    5688                onShow : function() 
    5789                { 
    58                         this.editObj = false; 
    59                         this.fakeObj = false; 
    60                         this.editMode = false; 
     90                        var selection = editor.getSelection(), 
     91                                fullySelected = selection.getSelectedElement(), 
     92                                partialSelected; 
    6193 
    62                         var selection = editor.getSelection(); 
    63                         var element = selection.getSelectedElement(); 
    64                         if ( element && element.data( 'cke-real-element-type' ) && element.data( 'cke-real-element-type' ) == 'anchor' ) 
     94                        // Detect the anchor under selection. 
     95                        if ( fullySelected ) 
    6596                        { 
    66                                 this.fakeObj = element; 
    67                                 element = editor.restoreRealElement( this.fakeObj ); 
    68                                 loadElements.apply( this, [ editor, selection, element ] ); 
    69                                 selection.selectElement( this.fakeObj ); 
    70                         } 
     97                                if ( CKEDITOR.plugins.link.fakeAnchor ) 
     98                                { 
     99                                        var realElement = CKEDITOR.plugins.link.tryRestoreFakeAnchor( editor, fullySelected ); 
     100                                        realElement && loadElements.call( this, realElement ); 
     101                                        this._.selectedElement = fullySelected; 
     102                                } 
     103                                else if ( fullySelected.is( 'a' ) && fullySelected.hasAttribute( 'name' ) ) 
     104                                        loadElements.call( this, fullySelected ); 
     105                        } 
     106                        else 
     107                        { 
     108                                partialSelected = CKEDITOR.plugins.link.getSelectedLink( editor ); 
     109                                if ( partialSelected ) 
     110                                { 
     111                                        loadElements.call( this, partialSelected ); 
     112                                        selection.selectElement( partialSelected ); 
     113                                } 
     114                        } 
     115 
    71116                        this.getContentElement( 'info', 'txtName' ).focus(); 
    72117                }, 
    73118                contents : [ 
  • _source/plugins/htmldataprocessor/plugin.js

     
    9595        delete blockLikeTags.pre; 
    9696        var defaultDataFilterRules = 
    9797        { 
    98                 elements : { 
    99                         a : function( element ) 
    100                         { 
    101                                 var attrs = element.attributes; 
    102                                 if ( attrs && attrs[ 'data-cke-saved-name' ] ) 
    103                                         attrs[ 'class' ] = ( attrs[ 'class' ] ? attrs[ 'class' ] + ' ' : '' ) + 'cke_anchor'; 
    104                         } 
    105                 }, 
     98                elements : {}, 
    10699                attributeNames : 
    107100                [ 
    108101                        // Event attributes (onXYZ) must not be directly set. They can become 
  • _source/plugins/link/dialogs/link.js

     
    235235                        advAttr( 'advTabIndex', 'tabindex' ); 
    236236                        advAttr( 'advTitle', 'title' ); 
    237237                        advAttr( 'advContentType', 'type' ); 
    238                         advAttr( 'advCSSClasses', 'class' ); 
     238                        CKEDITOR.plugins.link.synAnchorSelector ? 
     239                                retval.adv.advCSSClasses = getLinkClass( element ) 
     240                                : advAttr( 'advCSSClasses', 'class' ); 
    239241                        advAttr( 'advCharset', 'charset' ); 
    240242                        advAttr( 'advStyles', 'style' ); 
    241243                        advAttr( 'advRel', 'rel' ); 
    242244                } 
    243245 
    244246                // Find out whether we have any anchors in the editor. 
    245                 // Get all IMG elements in CK document. 
    246                 var elements = editor.document.getElementsByTag( 'img' ), 
    247                         realAnchors = new CKEDITOR.dom.nodeList( editor.document.$.anchors ), 
    248                         anchors = retval.anchors = []; 
     247                var anchorList = new CKEDITOR.dom.nodeList( editor.document.$.anchors ), 
     248                        anchors = retval.anchors = [], 
     249                        item; 
    249250 
    250                 for ( var i = 0; i < elements.count() ; i++ ) 
     251                for ( var i = 0, count = anchorList.count(); i < count; i++ ) 
    251252                { 
    252                         var item = elements.getItem( i ); 
    253                         if ( item.data( 'cke-realelement' ) && item.data( 'cke-real-element-type' ) == 'anchor' ) 
    254                                 anchors.push( editor.restoreRealElement( item ) ); 
    255                 } 
    256  
    257                 for ( i = 0 ; i < realAnchors.count() ; i++ ) 
    258                         anchors.push( realAnchors.getItem( i ) ); 
    259  
    260                 for ( i = 0 ; i < anchors.length ; i++ ) 
    261                 { 
    262                         item = anchors[ i ]; 
     253                        item = anchorList.getItem( i ); 
    263254                        anchors[ i ] = { name : item.getAttribute( 'name' ), id : item.getAttribute( 'id' ) }; 
    264255                } 
    265256 
    266257                // Record down the selected element in the dialog. 
    267258                this._.selectedElement = element; 
    268  
    269259                return retval; 
    270260        }; 
    271261 
     
    369359                return 'String.fromCharCode(' + encodedChars.join( ',' ) + ')'; 
    370360        } 
    371361 
     362        function getLinkClass( ele ) 
     363        { 
     364                var className = ele.getAttribute( 'class' ); 
     365                return className ? className.replace( /\s*(?:cke_anchor_empty|cke_anchor)(?:\s*$)?/g, '' ) : ''; 
     366        } 
     367 
    372368        var commonLang = editor.lang.common, 
    373369                linkLang = editor.lang.link; 
    374370 
     
    11511147                ], 
    11521148                onShow : function() 
    11531149                { 
    1154                         this.fakeObj = false; 
    1155  
    11561150                        var editor = this.getParentEditor(), 
    11571151                                selection = editor.getSelection(), 
    11581152                                element = null; 
     
    11601154                        // Fill in all the relevant fields if there's already one link selected. 
    11611155                        if ( ( element = plugin.getSelectedLink( editor ) ) && element.hasAttribute( 'href' ) ) 
    11621156                                selection.selectElement( element ); 
    1163                         else if ( ( element = selection.getSelectedElement() ) && element.is( 'img' ) 
    1164                                         && element.data( 'cke-real-element-type' ) 
    1165                                         && element.data( 'cke-real-element-type' ) == 'anchor' ) 
    1166                         { 
    1167                                 this.fakeObj = element; 
    1168                                 element = editor.restoreRealElement( this.fakeObj ); 
    1169                                 selection.selectElement( this.fakeObj ); 
    1170                         } 
    11711157                        else 
    11721158                                element = null; 
    11731159 
     
    13021288                                advAttr( 'advAccessKey', 'accessKey' ); 
    13031289 
    13041290                                if ( data.adv[ 'advName' ] ) 
    1305                                 { 
    13061291                                        attributes[ 'name' ] = attributes[ 'data-cke-saved-name' ] = data.adv[ 'advName' ]; 
    1307                                         attributes[ 'class' ] = ( attributes[ 'class' ] ? attributes[ 'class' ] + ' ' : '' ) + 'cke_anchor'; 
    1308                                 } 
    13091292                                else 
    13101293                                        removeAttributes = removeAttributes.concat( [ 'data-cke-saved-name', 'name' ] ); 
    13111294 
     
    13501333                                        href = element.data( 'cke-saved-href' ), 
    13511334                                        textView = element.getHtml(); 
    13521335 
    1353                                 // IE BUG: Setting the name attribute to an existing link doesn't work. 
    1354                                 // Must re-create the link from weired syntax to workaround. 
    1355                                 if ( CKEDITOR.env.ie && !( CKEDITOR.document.$.documentMode >= 8 ) && attributes.name != element.getAttribute( 'name' ) ) 
    1356                                 { 
    1357                                         var newElement = new CKEDITOR.dom.element( '<a name="' + CKEDITOR.tools.htmlEncode( attributes.name ) + '">', 
    1358                                                         editor.document ); 
    1359  
    1360                                         selection = editor.getSelection(); 
    1361  
    1362                                         element.copyAttributes( newElement, { name : 1 } ); 
    1363                                         element.moveChildren( newElement ); 
    1364                                         newElement.replace( element ); 
    1365                                         element = newElement; 
    1366  
    1367                                         selection.selectElement( element ); 
    1368                                 } 
    1369  
    13701336                                element.setAttributes( attributes ); 
    13711337                                element.removeAttributes( removeAttributes ); 
     1338 
     1339                                if ( data.adv && data.adv.advName && CKEDITOR.plugins.link.synAnchorSelector ) 
     1340                                        element.addClass( element.getChildCount() ? 'cke_anchor' : 'cke_anchor_empty' ); 
     1341 
    13721342                                // Update text view when user changes protocol (#4612). 
    13731343                                if ( href == textView || data.type == 'email' && textView.indexOf( '@' ) != -1 ) 
    13741344                                { 
     
    13761346                                        element.setHtml( data.type == 'email' ? 
    13771347                                                data.email.address : attributes[ 'data-cke-saved-href' ] ); 
    13781348                                } 
    1379                                 // Make the element display as an anchor if a name has been set. 
    1380                                 if ( element.getAttribute( 'name' ) ) 
    1381                                         element.addClass( 'cke_anchor' ); 
    1382                                 else 
    1383                                         element.removeClass( 'cke_anchor' ); 
    13841349 
    1385                                 if ( this.fakeObj ) 
    1386                                         editor.createFakeElement( element, 'cke_anchor', 'anchor' ).replace( this.fakeObj ); 
    1387  
    13881350                                delete this._.selectedElement; 
    13891351                        } 
    13901352                }, 
  • _source/plugins/elementspath/plugin.js

     
    124124 
    125125                                        while ( element ) 
    126126                                        { 
    127                                                 var ignore = 0; 
     127                                                var ignore = 0, 
     128                                                        name; 
     129 
     130                                                if ( element.data( 'cke-real-element-type' ) ) 
     131                                                        name = element.data( 'cke-real-element-type' ); 
     132                                                else 
     133                                                        name = element.getName(); 
     134 
    128135                                                for ( var i = 0; i < filters.length; i++ ) 
    129136                                                { 
    130                                                         if ( filters[ i ]( element ) === false ) 
     137                                                        var ret = filters[ i ]( element, name ); 
     138                                                        if ( ret === false ) 
    131139                                                        { 
    132140                                                                ignore = 1; 
    133141                                                                break; 
    134142                                                        } 
     143                                                        name = ret || name; 
    135144                                                } 
    136145 
    137146                                                if ( !ignore ) 
    138147                                                { 
    139148                                                        var index = elementsList.push( element ) - 1; 
    140                                                         var name; 
    141                                                         if ( element.data( 'cke-real-element-type' ) ) 
    142                                                                 name = element.data( 'cke-real-element-type' ); 
    143                                                         else 
    144                                                                 name = element.getName(); 
    145149 
    146150                                                        // Use this variable to add conditional stuff to the 
    147151                                                        // HTML (because we are doing it in reverse order... unshift). 
  • _source/plugins/link/plugin.js

     
    3030                CKEDITOR.dialog.add( 'anchor', this.path + 'dialogs/anchor.js' ); 
    3131 
    3232                // Add the CSS styles for anchor placeholders. 
    33                 var side = editor.lang.dir == 'rtl' ? 'right' : 'left'; 
     33 
     34                var side = ( editor.lang.dir == 'rtl' ? 'right' : 'left' ); 
     35                var basicCss =  
     36                        'background:url(' + CKEDITOR.getUrl( this.path + 'images/anchor.gif' ) + ') no-repeat ' + side + ' center;' + 
     37                        'border:1px dotted #00f;'; 
     38 
    3439                editor.addCss( 
    35                         'img.cke_anchor' + 
     40                        'a.cke_anchor,a.cke_anchor_empty' + 
     41                        // IE6 breaks with the following selectors. 
     42                        ( ( CKEDITOR.env.ie && CKEDITOR.env.version < 7 ) ? '' : 
     43                                ',a[name],a[data-cke-saved-name]' ) + 
    3644                        '{' + 
    37                                 'background-image: url(' + CKEDITOR.getUrl( this.path + 'images/anchor.gif' ) + ');' + 
    38                                 'background-position: center center;' + 
    39                                 'background-repeat: no-repeat;' + 
    40                                 'border: 1px solid #a9a9a9;' + 
    41                                 'width: 18px !important;' + 
    42                                 'height: 18px !important;' + 
    43                         '}\n' + 
    44                         'a.cke_anchor' + 
    45                         '{' + 
    46                                 'background-image: url(' + CKEDITOR.getUrl( this.path + 'images/anchor.gif' ) + ');' + 
    47                                 'background-position: ' + side + ' center;' + 
    48                                 'background-repeat: no-repeat;' + 
    49                                 'border: 1px solid #a9a9a9;' + 
    50                                 'padding-' + side + ': 18px;' + 
    51                         '}' 
    52                         ); 
     45                                basicCss + 
     46                                'padding-' + side + ':18px;' + 
     47                                // Show the arrow cursor for the anchor image (FF at least). 
     48                                'cursor:auto;' + 
     49                        '}' + 
     50                        ( ( CKEDITOR.env.ie && CKEDITOR.env.version > 8 ) ? 'a[name]:empty,' : '' ) + 
     51                        'a.cke_anchor_empty' + 
     52                        '{' + 
     53                                // Make empty anchor selectable on IE. 
     54                                'display:inline-block;' + 
     55                        '}' + 
     56                        'img.cke_anchor' + 
     57                        '{' + 
     58                                basicCss + 
     59                                'width:16px;' + 
     60                                'min-height:15px;' + 
     61                                // The default line-height on IE. 
     62                                'height:1.15em;' + 
     63                                // Opera works better with "middle" (even if not perfect) 
     64                                'vertical-align:' + ( CKEDITOR.env.opera ? 'middle' : 'text-bottom' ) + ';' + 
     65                        '}'); 
    5366 
    5467                // Register selection change handler for the unlink button. 
    5568                 editor.on( 'selectionChange', function( evt ) 
     
    6073                                 */ 
    6174                                var command = editor.getCommand( 'unlink' ), 
    6275                                        element = evt.data.path.lastElement && evt.data.path.lastElement.getAscendant( 'a', true ); 
    63                                 if ( element && element.getName() == 'a' && element.getAttribute( 'href' ) ) 
     76                                if ( element && element.getName() == 'a' && element.getAttribute( 'href' ) && element.getChildCount() ) 
    6477                                        command.setState( CKEDITOR.TRISTATE_OFF ); 
    6578                                else 
    6679                                        command.setState( CKEDITOR.TRISTATE_DISABLED ); 
     
    7386                                if ( !element.isReadOnly() ) 
    7487                                { 
    7588                                        if ( element.is( 'a' ) ) 
    76                                                 evt.data.dialog =  ( element.getAttribute( 'name' ) && !element.getAttribute( 'href' ) ) ? 'anchor' : 'link'; 
    77                                         else if ( element.is( 'img' ) && element.data( 'cke-real-element-type' ) == 'anchor' ) 
     89                                        { 
     90                                                evt.data.dialog = ( element.getAttribute( 'name' ) && ( !element.getAttribute( 'href' ) || !element.getChildCount() ) ) ? 'anchor' : 'link'; 
     91                                                editor.getSelection().selectElement( element ); 
     92                                        } 
     93                                        else if ( CKEDITOR.plugins.link.tryRestoreFakeAnchor( editor, element ) ) 
    7894                                                evt.data.dialog = 'anchor'; 
    7995                                } 
    8096                        }); 
     
    117133                                        if ( !element || element.isReadOnly() ) 
    118134                                                return null; 
    119135 
    120                                         var isAnchor = ( element.is( 'img' ) && element.data( 'cke-real-element-type' ) == 'anchor' ); 
     136                                        var anchor = CKEDITOR.plugins.link.tryRestoreFakeAnchor( editor, element ); 
    121137 
    122                                         if ( !isAnchor ) 
    123                                         { 
    124                                                 if ( !( element = CKEDITOR.plugins.link.getSelectedLink( editor ) ) ) 
     138                                        if ( !anchor && !( anchor = CKEDITOR.plugins.link.getSelectedLink( editor ) ) ) 
    125139                                                        return null; 
    126140 
    127                                                 isAnchor = ( element.getAttribute( 'name' ) && !element.getAttribute( 'href' ) ); 
    128                                         } 
     141                                        var menu = {}; 
    129142 
    130                                         return isAnchor ? 
    131                                                         { anchor : CKEDITOR.TRISTATE_OFF } : 
    132                                                         { link : CKEDITOR.TRISTATE_OFF, unlink : CKEDITOR.TRISTATE_OFF }; 
     143                                        if ( anchor.getAttribute( 'href' ) && anchor.getChildCount() ) 
     144                                                menu = { link : CKEDITOR.TRISTATE_OFF, unlink : CKEDITOR.TRISTATE_OFF }; 
     145 
     146                                        if ( anchor && anchor.hasAttribute( 'name' ) ) 
     147                                                menu.anchor = CKEDITOR.TRISTATE_OFF; 
     148 
     149                                        return menu; 
    133150                                }); 
    134151                } 
    135152        }, 
     
    139156                // Register a filter to displaying placeholders after mode change. 
    140157 
    141158                var dataProcessor = editor.dataProcessor, 
    142                         dataFilter = dataProcessor && dataProcessor.dataFilter; 
     159                        dataFilter = dataProcessor && dataProcessor.dataFilter, 
     160                        htmlFilter = dataProcessor && dataProcessor.htmlFilter, 
     161                        pathFilters = editor._.elementsPath.filters; 
    143162 
    144163                if ( dataFilter ) 
    145164                { 
     
    150169                                                a : function( element ) 
    151170                                                { 
    152171                                                        var attributes = element.attributes; 
    153                                                         if ( attributes.name && !attributes.href ) 
     172                                                        if ( !attributes.name ) 
     173                                                                return; 
     174 
     175                                                        var isEmpty = !element.children.length; 
     176 
     177                                                        if ( CKEDITOR.plugins.link.synAnchorSelector ) 
     178                                                        { 
     179                                                                // IE needs a specific class name to be applied 
     180                                                                // to the anchors, for appropriate styling. 
     181                                                                var ieClass = isEmpty ? 'cke_anchor_empty' : 'cke_anchor'; 
     182                                                                var cls = attributes[ 'class' ]; 
     183                                                                if ( attributes.name && ( !cls || cls.indexOf( ieClass ) < 0 ) ) 
     184                                                                        attributes[ 'class' ] = ( cls || '' ) + ' ' + ieClass; 
     185 
     186                                                                if ( isEmpty && CKEDITOR.plugins.link.emptyAnchorFix ) 
     187                                                                { 
     188                                                                        attributes.contenteditable = 'false'; 
     189                                                                        attributes[ 'data-cke-editable' ] = 1; 
     190                                                                } 
     191                                                        } 
     192                                                        else if ( CKEDITOR.plugins.link.fakeAnchor && isEmpty ) 
    154193                                                                return editor.createFakeParserElement( element, 'cke_anchor', 'anchor' ); 
    155194                                                } 
    156195                                        } 
    157196                                }); 
    158197                } 
     198 
     199                if ( CKEDITOR.plugins.link.emptyAnchorFix && htmlFilter ) 
     200                { 
     201                        htmlFilter.addRules( 
     202                                { 
     203                                        elements : 
     204                                        { 
     205                                                a : function( element ) 
     206                                                { 
     207                                                        delete element.attributes.contenteditable; 
     208                                                } 
     209                                        } 
     210                                }); 
     211                } 
     212 
     213                if ( pathFilters ) 
     214                { 
     215                        pathFilters.push( function( element, name ) 
     216                                { 
     217                                        if ( name == 'a' ) 
     218                                        { 
     219                                                if ( CKEDITOR.plugins.link.tryRestoreFakeAnchor( editor, element ) ||  
     220                                                        ( element.getAttribute( 'name' ) && ( !element.getAttribute( 'href' ) || !element.getChildCount() ) ) ) 
     221                                                { 
     222                                                        return 'anchor'; 
     223                                                } 
     224                                        } 
     225                                }); 
     226                } 
    159227        }, 
    160228 
    161229        requires : [ 'fakeobjects' ] 
     
    196264                        return root.getAscendant( 'a', true ); 
    197265                } 
    198266                catch( e ) { return null; } 
    199         } 
     267        }, 
     268 
     269        // Opera and WebKit don't make it possible to select empty anchors. Fake 
     270        // elements must be used for them. 
     271        fakeAnchor : CKEDITOR.env.opera || CKEDITOR.env.webkit, 
     272 
     273        // For browsers that don't support CSS3 a[name]:empty(). 
     274        synAnchorSelector : CKEDITOR.env.ie && CKEDITOR.env.version < 9, 
     275 
     276        // For browsers that have editing issue with empty anchor. 
     277        emptyAnchorFix : CKEDITOR.env.ie && CKEDITOR.env.version < 8, 
     278 
     279        tryRestoreFakeAnchor : function( editor, element ) 
     280        { 
     281                if ( element && element.data( 'cke-real-element-type' ) && element.data( 'cke-real-element-type' ) == 'anchor' ) 
     282                { 
     283                        var link  = editor.restoreRealElement( element ); 
     284                        if ( link.data( 'cke-saved-name' ) ) 
     285                                return link; 
     286                } 
     287        } 
    200288}; 
    201289 
    202290CKEDITOR.unlinkCommand = function(){}; 
© 2003 – 2011 CKSource – Frederico Knabben. All rights reserved. | Terms of use | Privacy policy