Ticket #3582: 3582_13.patch

File 3582_13.patch, 21.4 KB (added by Frederico Caldeira Knabben, 8 years 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                        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;
    892906
     907                                                return standard.call( this, name );
     908                                        }
     909                                :
     910                                        standard;
     911                })(),
     912
    893913                /**
    894914                 * Hides this element (display:none).
    895915                 * @example
  • _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/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 );
    267 
    268                 if ( this.getName() == 'input' )
     264        CKEDITOR.dom.element.prototype.hasAttribute = CKEDITOR.tools.override( CKEDITOR.dom.element.prototype.hasAttribute,
     265                function( original )
    269266                {
    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                 }
     267                        return function( name )
     268                                {
     269                                        var $attr = this.$.attributes.getNamedItem( name );
    281270
    282                 return !!( $attr && $attr.specified );
    283         };
     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                                        }
     284
     285                                        return original.apply( this, arguments );
     286                                };
     287                });
    284288}
  • _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/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 );
     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 );
    3844                        }
     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 );
     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                                }
    5280                        }
     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 );
     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 );
    70105                        }
     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/link/dialogs/link.js

     
    235235                        advAttr( 'advTabIndex', 'tabindex' );
    236236                        advAttr( 'advTitle', 'title' );
    237237                        advAttr( 'advContentType', 'type' );
    238                         advAttr( 'advCSSClasses', 'class' );
    239238                        advAttr( 'advCharset', 'charset' );
    240239                        advAttr( 'advStyles', 'style' );
    241240                        advAttr( 'advRel', 'rel' );
     241
     242                        retval.adv.advCSSClasses = getLinkClass( element ) || '';
    242243                }
    243244
    244245                // 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 = [];
     246                var anchorList = new CKEDITOR.dom.nodeList( editor.document.$.anchors ),
     247                        anchors = retval.anchors = [],
     248                        item;
    249249
    250                 for ( var i = 0; i < elements.count() ; i++ )
     250                for ( var i = 0, count = anchorList.count(); i < count; i++ )
    251251                {
    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 ];
     252                        item = anchorList.getItem( i );
    263253                        anchors[ i ] = { name : item.getAttribute( 'name' ), id : item.getAttribute( 'id' ) };
    264254                }
    265255
    266256                // Record down the selected element in the dialog.
    267257                this._.selectedElement = element;
    268 
    269258                return retval;
    270259        };
    271260
     
    369358                return 'String.fromCharCode(' + encodedChars.join( ',' ) + ')';
    370359        }
    371360
     361        function getLinkClass( ele )
     362        {
     363                var className = ele.getAttribute( 'class' );
     364                return className ? className.replace( /\s*(?:cke_anchor_empty|cke_anchor)(?:\s*$)?/g, '' ) : '';
     365        }
     366
    372367        var commonLang = editor.lang.common,
    373368                linkLang = editor.lang.link;
    374369
     
    11511146                ],
    11521147                onShow : function()
    11531148                {
    1154                         this.fakeObj = false;
    1155 
    11561149                        var editor = this.getParentEditor(),
    11571150                                selection = editor.getSelection(),
    11581151                                element = null;
     
    11601153                        // Fill in all the relevant fields if there's already one link selected.
    11611154                        if ( ( element = plugin.getSelectedLink( editor ) ) && element.hasAttribute( 'href' ) )
    11621155                                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                         }
    11711156                        else
    11721157                                element = null;
    11731158
     
    13021287                                advAttr( 'advAccessKey', 'accessKey' );
    13031288
    13041289                                if ( data.adv[ 'advName' ] )
    1305                                 {
    13061290                                        attributes[ 'name' ] = attributes[ 'data-cke-saved-name' ] = data.adv[ 'advName' ];
    1307                                         attributes[ 'class' ] = ( attributes[ 'class' ] ? attributes[ 'class' ] + ' ' : '' ) + 'cke_anchor';
    1308                                 }
    13091291                                else
    13101292                                        removeAttributes = removeAttributes.concat( [ 'data-cke-saved-name', 'name' ] );
    13111293
     
    13501332                                        href = element.data( 'cke-saved-href' ),
    13511333                                        textView = element.getHtml();
    13521334
    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 
    13701335                                element.setAttributes( attributes );
    13711336                                element.removeAttributes( removeAttributes );
     1337
     1338                                if ( data.adv && data.adv.advName )
     1339                                        element.addClass( element.getChildCount() ? 'cke_anchor' : 'cke_anchor_empty' );
     1340
    13721341                                // Update text view when user changes protocol (#4612).
    13731342                                if ( href == textView || data.type == 'email' && textView.indexOf( '@' ) != -1 )
    13741343                                {
     
    13761345                                        element.setHtml( data.type == 'email' ?
    13771346                                                data.email.address : attributes[ 'data-cke-saved-href' ] );
    13781347                                }
    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' );
    13841348
    1385                                 if ( this.fakeObj )
    1386                                         editor.createFakeElement( element, 'cke_anchor', 'anchor' ).replace( this.fakeObj );
    1387 
    13881349                                delete this._.selectedElement;
    13891350                        }
    13901351                },
  • _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(
     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]' ) +
     44                        '{' +
     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                        '}' +
    3556                        'img.cke_anchor' +
    3657                        '{' +
    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                         );
     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 )
     
    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.env.ie && CKEDITOR.env.version < 9 )
     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.env.version < 8 )
     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.env.ie && 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' ) ) )
     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; }
     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        tryRestoreFakeAnchor : function( editor, element )
     274        {
     275                if ( element && element.data( 'cke-real-element-type' ) && element.data( 'cke-real-element-type' ) == 'anchor' )
     276                {
     277                        var link  = editor.restoreRealElement( element );
     278                        if ( link.data( 'cke-saved-name' ) )
     279                                return link;
     280                }
    199281        }
    200282};
    201283
© 2003 – 2019 CKSource – Frederico Knabben. All rights reserved. | Terms of use | Privacy policy