Ticket #3582: 3582_7.patch
File 3582_7.patch, 21.7 KB (added by , 13 years ago) |
---|
-
_source/plugins/dialog/plugin.js
927 927 var editor = this._.editor; 928 928 editor.focus(); 929 929 930 if ( editor.mode == 'wysiwyg' && CKEDITOR.env.ie)930 if ( editor.mode == 'wysiwyg' ) 931 931 { 932 932 var selection = editor.getSelection(); 933 933 selection && selection.unlock( true ); … … 2988 2988 */ 2989 2989 openDialog : function( dialogName, callback ) 2990 2990 { 2991 if ( this.mode == 'wysiwyg' && CKEDITOR.env.ie)2991 if ( this.mode == 'wysiwyg' ) 2992 2992 { 2993 2993 var selection = this.getSelection(); 2994 2994 selection && selection.lock(); -
_source/plugins/link/dialogs/anchor.js
6 6 CKEDITOR.dialog.add( 'anchor', function( editor ) 7 7 { 8 8 // Function called in onShow to load selected element. 9 var loadElements = function( e ditor, selection, element )9 var loadElements = function( element ) 10 10 { 11 this.editMode = true; 12 this.editObj = element; 11 this._.selectedElement = element; 13 12 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 || '' ); 19 15 }; 20 16 21 17 return { … … 24 20 minHeight : 60, 25 21 onOk : function() 26 22 { 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' ); 23 var name = this.getValueOf( 'info', 'txtName' ); 24 var attributes = 25 { 26 name : name, 27 'data-cke-saved-name' : name 28 }; 32 29 33 // Move contents and attributes of old anchor to new anchor. 34 if ( this.editMode ) 30 if ( this._.selectedElement ) 35 31 { 36 this.editObj.copyAttributes( element, { name : 1 } ); 37 this.editObj.moveChildren( element ); 38 } 32 if ( this._.selectedElement.data( 'cke-realelement' ) ) 33 { 34 var newFake = CKEDITOR.plugins.link.createFakeAnchor( editor, editor.document.createElement( 'a', { attributes: attributes } ) ); 35 newFake.replace( this._.selectedElement ); 36 } 37 else 38 this._.selectedElement.setAttributes( attributes ); 39 } 40 else 41 { 42 var sel = editor.getSelection(), 43 range = sel && sel.getRanges()[ 0 ]; 39 44 40 // Set name. 41 element.data( 'cke-saved-name', false ); 42 element.setAttribute( 'name', name ); 43 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 } 45 // Empty anchor 46 if ( range.collapsed ) 47 { 48 var anchor = editor.document.createElement( 'a', { attributes: attributes } ); 49 if ( CKEDITOR.plugins.link.fakeAnchor ) 50 anchor = CKEDITOR.plugins.link.createFakeAnchor( editor, anchor ); 51 editor.insertElement( anchor ); 52 } 53 else 54 { 55 // Apply style. 56 var style = new CKEDITOR.style( { element : 'a', attributes : attributes } ); 57 style.type = CKEDITOR.STYLE_INLINE; 58 style.apply( editor.document ); 59 } 60 } 61 }, 53 62 54 return true; 63 onHide : function() 64 { 65 delete this._.selectedElement; 55 66 }, 67 56 68 onShow : function() 57 69 { 58 this.editObj = false;59 this.fakeObj = false;60 this.editMode = false;70 var selection = editor.getSelection(), 71 fullySelected = selection.getSelectedElement(), 72 partialSelected; 61 73 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' ) 74 // Detect the anchor under selection. 75 if ( fullySelected ) 65 76 { 66 this.fakeObj = element; 67 element = editor.restoreRealElement( this.fakeObj ); 68 loadElements.apply( this, [ editor, selection, element ] ); 69 selection.selectElement( this.fakeObj ); 70 } 77 if ( CKEDITOR.plugins.link.fakeAnchor ) 78 { 79 var realElement = CKEDITOR.plugins.link.tryRestoreFakeAnchor( editor, fullySelected ); 80 realElement && loadElements.call( this, realElement ); 81 this._.selectedElement = fullySelected; 82 } 83 else if ( fullySelected.is( 'a' ) && fullySelected.hasAttribute( 'name' ) ) 84 loadElements.call( this, fullySelected ); 85 } 86 else 87 { 88 partialSelected = CKEDITOR.plugins.link.getSelectedLink( editor ); 89 if ( partialSelected ) 90 { 91 loadElements.call( this, partialSelected ); 92 selection.selectElement( partialSelected ); 93 } 94 } 95 71 96 this.getContentElement( 'info', 'txtName' ).focus(); 72 97 }, 73 98 contents : [ -
_source/plugins/wysiwygarea/plugin.js
62 62 if ( range.checkReadOnly() ) 63 63 return; 64 64 65 if ( CKEDITOR.env.ie ) 66 { 67 var selIsLocked = selection.isLocked; 65 var selIsLocked = selection.isLocked; 66 selIsLocked && selection.unlock(); 68 67 69 if ( selIsLocked ) 70 selection.unlock(); 71 68 if ( CKEDITOR.env.ie ) 69 { 72 70 var $sel = selection.getNative(); 73 71 74 72 // Delete control selections to avoid IE bugs on pasteHTML. … … 99 97 } 100 98 catch (e) {} 101 99 102 if ( selIsLocked )103 this.getSelection().lock();104 100 } 105 101 else 106 102 this.document.$.execCommand( 'inserthtml', false, data ); 107 103 104 selIsLocked && this.getSelection().lock(); 105 108 106 // Webkit does not scroll to the cursor position after pasting (#5558) 109 107 if ( CKEDITOR.env.webkit ) 110 108 { … … 636 634 var element = evt.data.getTarget(), 637 635 data = { element : element, dialog : '' }; 638 636 editor.fire( 'doubleclick', data ); 639 data.dialog && editor.openDialog( data.dialog ); 640 }); 637 data.dialog && editor.openDialog( data.dialog, function() 638 { 639 // Fully embrace the element under click in the to-be-locked selection. 640 element && editor.getSelection().selectElement( element ) 641 }); 642 }); 641 643 642 644 // Prevent automatic submission in IE #6336 643 645 CKEDITOR.env.ie && domDocument.on( 'click', function( evt ) -
_source/plugins/htmldataprocessor/plugin.js
95 95 delete blockLikeTags.pre; 96 96 var defaultDataFilterRules = 97 97 { 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 : {}, 106 99 attributeNames : 107 100 [ 108 101 // Event attributes (onXYZ) must not be directly set. They can become -
_source/plugins/link/dialogs/link.js
242 242 } 243 243 244 244 // 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 = []; 245 var anchorList = new CKEDITOR.dom.nodeList( editor.document.$.anchors ), 246 anchors = retval.anchors = [], 247 item; 249 248 250 for ( var i = 0 ; i < elements.count(); i++ )249 for ( var i = 0, count = anchorList.count(); i < count; i++ ) 251 250 { 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 ]; 251 item = anchorList.getItem( i ); 263 252 anchors[ i ] = { name : item.getAttribute( 'name' ), id : item.getAttribute( 'id' ) }; 264 253 } 265 254 266 255 // Record down the selected element in the dialog. 267 256 this._.selectedElement = element; 268 269 257 return retval; 270 258 }; 271 259 … … 1151 1139 ], 1152 1140 onShow : function() 1153 1141 { 1154 this.fakeObj = false;1155 1156 1142 var editor = this.getParentEditor(), 1157 1143 selection = editor.getSelection(), 1158 1144 element = null; … … 1160 1146 // Fill in all the relevant fields if there's already one link selected. 1161 1147 if ( ( element = plugin.getSelectedLink( editor ) ) && element.hasAttribute( 'href' ) ) 1162 1148 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 }1171 1149 else 1172 1150 element = null; 1173 1151 … … 1302 1280 advAttr( 'advAccessKey', 'accessKey' ); 1303 1281 1304 1282 if ( data.adv[ 'advName' ] ) 1305 {1306 1283 attributes[ 'name' ] = attributes[ 'data-cke-saved-name' ] = data.adv[ 'advName' ]; 1307 attributes[ 'class' ] = ( attributes[ 'class' ] ? attributes[ 'class' ] + ' ' : '' ) + 'cke_anchor';1308 }1309 1284 else 1310 1285 removeAttributes = removeAttributes.concat( [ 'data-cke-saved-name', 'name' ] ); 1311 1286 … … 1350 1325 href = element.data( 'cke-saved-href' ), 1351 1326 textView = element.getHtml(); 1352 1327 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 1370 1328 element.setAttributes( attributes ); 1371 1329 element.removeAttributes( removeAttributes ); 1372 1330 // Update text view when user changes protocol (#4612). … … 1376 1334 element.setHtml( data.type == 'email' ? 1377 1335 data.email.address : attributes[ 'data-cke-saved-href' ] ); 1378 1336 } 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 else1383 element.removeClass( 'cke_anchor' );1384 1337 1385 if ( this.fakeObj )1386 editor.createFakeElement( element, 'cke_anchor', 'anchor' ).replace( this.fakeObj );1387 1388 1338 delete this._.selectedElement; 1389 1339 } 1390 1340 }, -
_source/plugins/elementspath/plugin.js
124 124 125 125 while ( element ) 126 126 { 127 var ignore = 0; 127 var index = elementsList.push( element ) - 1; 128 var name; 129 if ( element.data( 'cke-real-element-type' ) ) 130 name = element.data( 'cke-real-element-type' ); 131 else 132 name = element.getName(); 133 134 var ignore = 0, retval; 128 135 for ( var i = 0; i < filters.length; i++ ) 129 136 { 130 if ( filters[ i ]( element ) === false ) 137 retval = filters[ i ]( element, name ); 138 if ( retval === false ) 131 139 { 132 140 ignore = 1; 133 141 break; 134 142 } 143 else 144 name = retval || name; 135 145 } 136 146 137 if ( !ignore ) 138 { 139 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(); 147 if ( ignore ) 148 continue; 145 149 146 147 148 150 // Use this variable to add conditional stuff to the 151 // HTML (because we are doing it in reverse order... unshift). 152 var extra = ''; 149 153 150 151 152 153 154 154 // Some browsers don't cancel key events in the keydown but in the 155 // keypress. 156 // TODO: Check if really needed for Gecko+Mac. 157 if ( env.opera || ( env.gecko && env.mac ) ) 158 extra += ' onkeypress="return false;"'; 155 159 156 157 158 159 160 // With Firefox, we need to force the button to redraw, otherwise it 161 // will remain in the focus state. 162 if ( env.gecko ) 163 extra += ' onblur="this.style.cssText = this.style.cssText;"'; 160 164 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 165 var label = editor.lang.elementsPath.eleTitle.replace( /%1/, name ); 166 html.unshift( 167 '<a' + 168 ' id="', idBase, index, '"' + 169 ' href="javascript:void(\'', name, '\')"' + 170 ' tabindex="-1"' + 171 ' title="', label, '"' + 172 ( ( CKEDITOR.env.gecko && CKEDITOR.env.version < 10900 ) ? 173 ' onfocus="event.preventBubble();"' : '' ) + 174 ' hidefocus="true" ' + 175 ' onkeydown="return CKEDITOR.tools.callFunction(', onKeyDownHandler, ',', index, ', event );"' + 176 extra , 177 ' onclick="CKEDITOR.tools.callFunction('+ onClickHanlder, ',', index, '); return false;"', 178 ' role="button" aria-labelledby="' + idBase + index + '_label">', 179 name, 180 '<span id="', idBase, index, '_label" class="cke_label">' + label + '</span>', 181 '</a>' ); 178 182 179 }180 183 181 184 if ( name == 'body' ) 182 185 break; -
_source/plugins/link/plugin.js
31 31 32 32 // Add the CSS styles for anchor placeholders. 33 33 var side = editor.lang.dir == 'rtl' ? 'right' : 'left'; 34 editor.addCss( 35 'img.cke_anchor' + 34 var anchorCss = 36 35 '{' + 37 'background-image: url(' + CKEDITOR.getUrl( this.path + 'images/anchor.gif' ) + ');' + 38 'background-position: center center;' + 39 'background-repeat: no-repeat;' + 36 'background: url(' + CKEDITOR.getUrl( this.path + 'images/anchor.gif' ) + ') no-repeat ' + side + ' center;' + 40 37 'border: 1px solid #a9a9a9;' + 41 'width: 18px !important;' + 42 'height: 18px !important;' + 43 '}\n' + 44 'a.cke_anchor' + 38 'padding-' + side + ': 18px;' + 39 '}', 40 fakeAnchorCss = 45 41 '{' + 46 'background-image: url(' + CKEDITOR.getUrl( this.path + 'images/anchor.gif' ) + ');' + 47 'background-position: ' + side + ' center;' + 48 'background-repeat: no-repeat;' + 42 'background: url(' + CKEDITOR.getUrl( this.path + 'images/anchor.gif' ) + ') no-repeat ' + side + ' center;' + 49 43 'border: 1px solid #a9a9a9;' + 50 ' padding-' + side + ': 18px;' +51 '}' 52 );44 'width:18px !important;height:18px !important;' + 45 '}', 46 emptyAnchorCss = '{display:inline-block;height:18px;vertical-align:middle;cursor:default;}'; 53 47 48 editor.addCss( 'a[name]:empty'+ emptyAnchorCss ); 49 editor.addCss( ( CKEDITOR.env.ie6Compat ? 'a.cke_anchor' : 'a[name],a[data-cke-saved-name]' ) + anchorCss ); 50 CKEDITOR.plugins.link.fakeAnchor && editor.addCss( 'img.cke_anchor' + fakeAnchorCss ); 51 54 52 // Register selection change handler for the unlink button. 55 53 editor.on( 'selectionChange', function( evt ) 56 54 { … … 74 72 { 75 73 if ( element.is( 'a' ) ) 76 74 evt.data.dialog = ( element.getAttribute( 'name' ) && !element.getAttribute( 'href' ) ) ? 'anchor' : 'link'; 77 else if ( element.is( 'img' ) && element.data( 'cke-real-element-type' ) == 'anchor')75 else if ( CKEDITOR.plugins.link.tryRestoreFakeAnchor( editor, element ) ) 78 76 evt.data.dialog = 'anchor'; 79 77 } 80 78 }); … … 117 115 if ( !element || element.isReadOnly() ) 118 116 return null; 119 117 120 var isAnchor = ( element.is( 'img' ) && element.data( 'cke-real-element-type' ) == 'anchor');118 var isAnchor = CKEDITOR.plugins.link.tryRestoreFakeAnchor( editor, element ); 121 119 122 120 if ( !isAnchor ) 123 121 { … … 139 137 // Register a filter to displaying placeholders after mode change. 140 138 141 139 var dataProcessor = editor.dataProcessor, 142 dataFilter = dataProcessor && dataProcessor.dataFilter; 140 dataFilter = dataProcessor && dataProcessor.dataFilter, 141 pathFilters = editor._.elementsPath.filters; 143 142 144 143 if ( dataFilter ) 145 144 { … … 150 149 a : function( element ) 151 150 { 152 151 var attributes = element.attributes; 153 if ( attributes.name && !attributes.href ) 154 return editor.createFakeParserElement( element, 'cke_anchor', 'anchor' ); 155 } 156 } 152 if ( !attributes.name ) 153 return; 154 155 if ( element.children.length ) 156 { 157 if ( CKEDITOR.env.ie6Compat ) 158 { 159 var cls = attributes[ 'class' ]; 160 if ( attributes.name && ( !cls || cls.indexOf( 'cke_anchor' ) < 0 ) ) 161 attributes[ 'class' ] = ( cls || '' ) + ' cke_anchor'; 162 } 163 } 164 else if (CKEDITOR.plugins.link.fakeAnchor ) 165 { 166 return editor.createFakeParserElement( element, 'cke_anchor', 'a' ); 167 } 168 } 169 } 157 170 }); 158 171 } 172 173 if ( pathFilters ) 174 { 175 pathFilters.push( function( element, name ) 176 { 177 if ( name == 'a' ) 178 { 179 var isFake = element.data( 'cke-real-element-type' ); 180 element = isFake ? editor.restoreRealElement( element ) : element; 181 if ( element.data( 'cke-saved-name' ) && !element.getChildren().count() ) 182 return 'anchor'; 183 } 184 }); 185 } 159 186 }, 160 187 161 188 requires : [ 'fakeobjects' ] … … 196 223 return root.getAscendant( 'a', true ); 197 224 } 198 225 catch( e ) { return null; } 199 } 226 }, 227 228 // Present empty anchor with fake element in only old IEs. (#3582) 229 fakeAnchor : CKEDITOR.env.ie && !CKEDITOR.env.ie9Compat, 230 231 createFakeAnchor : function( editor, anchor ) 232 { 233 return editor.createFakeElement( anchor, 'cke_anchor', 'a' ); 234 }, 235 236 tryRestoreFakeAnchor : function( editor, element ) 237 { 238 if ( element && element.data( 'cke-real-element-type' ) && element.data( 'cke-real-element-type' ) == 'a' ) 239 { 240 var link = editor.restoreRealElement( element ); 241 if ( link.data( 'cke-saved-name' ) ) 242 return link; 243 } 244 } 200 245 }; 201 246 202 247 CKEDITOR.unlinkCommand = function(){}; … … 240 285 linkShowAdvancedTab : true, 241 286 linkShowTargetTab : true 242 287 } ); 288 289 // Present a[name] as "cke_anchor" in IE6. 290 CKEDITOR.env.ie6Compat && ( function() 291 { 292 function markAnchor( org ) 293 { 294 var attrGet = org == elementProto.getAttribute; 295 296 return function( name, val ) 297 { 298 if ( this.getDocument().equals( CKEDITOR.document ) ) 299 return org.apply( this, arguments ); 300 301 var retval = org.apply( this, arguments ); 302 if ( this.is( 'a' ) ) 303 { 304 if ( name == 'name' ) 305 this[ val ? 'addClass' : 'removeClass' ]( 'cke_anchor' ); 306 else if ( name == 'class' && this.$.getAttribute( 'name' ) ) 307 attrGet ? retval = retval.replace( /\s*cke_anchor\s*/, '' ) : this.addClass( 'cke_anchor' ); 308 } 309 return retval; 310 }; 311 } 312 313 var elementProto = CKEDITOR.dom.element.prototype, 314 methods = [ 'getAttribute','setAttribute', 'removeAttribute' ]; 315 for ( var i = 0; i < methods.length; i++ ) 316 elementProto[ methods[ i ] ] = CKEDITOR.tools.override( elementProto[ methods [ i ] ], markAnchor ); 317 318 } )();