Index: _source/plugins/link/dialogs/link.js
===================================================================
--- _source/plugins/link/dialogs/link.js (revision 4917)
+++ _source/plugins/link/dialogs/link.js Thu Jan 28 15:33:32 CST 2010
@@ -84,7 +84,7 @@
var parseLink = function( editor, element )
{
- var href = element ? ( element.getAttribute( '_cke_saved_href' ) || element.getAttribute( 'href' ) ) : '',
+ var href = ( element && ( element.getAttribute( '_cke_saved_href' ) || element.getAttribute( 'href' ) ) ) || '',
emailMatch,
anchorMatch,
urlMatch,
@@ -351,6 +351,39 @@
return 'String.fromCharCode(' + encodedChars.join( ',' ) + ')';
}
+ function getPartialSelectedElement( editor, tagName )
+ {
+ try
+ {
+ var selection = editor.getSelection(),
+ ranges = selection.getRanges(),
+ range = ranges[0];
+
+ /* Have to deal with the following cases: (#4513)
+ li^nk
+ [link]
+ text[link]
+ li[nk]
+ ...
+ */
+
+ range.trim( false, false, true );
+
+ var selectedStartNode = range.getTouchedStartNode(),
+ selectedEndNode = range.getTouchedEndNode(),
+ elementAtStart = selectedStartNode.getAscendant( tagName, true ),
+ elementAtEnd = selectedEndNode.getAscendant( tagName, true );
+
+ if( elementAtStart.equals( elementAtEnd ) )
+ return elementAtStart;
+
+ }
+ catch(er)
+ {
+ return null;
+ }
+ }
+
return {
title : editor.lang.link.title,
minWidth : 350,
@@ -1119,30 +1152,21 @@
var editor = this.getParentEditor(),
selection = editor.getSelection(),
- ranges = selection.getRanges(),
- element = null,
- me = this;
- // Fill in all the relevant fields if there's already one link selected.
- if ( ranges.length == 1 )
- {
+ element = null;
- var rangeRoot = ranges[0].getCommonAncestor( true );
- element = rangeRoot.getAscendant( 'a', true );
- if ( element && element.getAttribute( 'href' ) )
- {
+ // Fill in all the relevant fields if there's already one link selected.
+ if ( ( element = getPartialSelectedElement( editor, 'a' ) ) && element.hasAttribute( 'href' ) )
- selection.selectElement( element );
+ selection.selectElement( element );
- }
- else if ( ( element = rangeRoot.getAscendant( 'img', true ) ) &&
- element.getAttribute( '_cke_real_element_type' ) &&
- element.getAttribute( '_cke_real_element_type' ) == 'anchor' )
+ else if ( ( element = selection.getSelectedElement() ) && element.is( 'img' )
+ && element.getAttribute( '_cke_real_element_type' )
+ && element.getAttribute( '_cke_real_element_type' ) == 'anchor' )
- {
- this.fakeObj = element;
- element = editor.restoreRealElement( this.fakeObj );
- selection.selectElement( this.fakeObj );
- }
- else
- element = null;
+ {
+ this.fakeObj = element;
+ element = editor.restoreRealElement( this.fakeObj );
+ selection.selectElement( this.fakeObj );
+ }
+ else
+ element = null;
- }
this.setupContent( parseLink.apply( this, [ editor, element ] ) );
},
Index: _source/core/dom/range.js
===================================================================
--- _source/core/dom/range.js (revision 4858)
+++ _source/core/dom/range.js Thu Jan 28 15:39:09 CST 2010
@@ -712,7 +712,14 @@
this.setEndAt( endNode, CKEDITOR.POSITION_AFTER_END );
},
- trim : function( ignoreStart, ignoreEnd )
+ /**
+ * Favor element as range containers over text node,
+ * optionally break text node into two when necessary.
+ * @param ignoreStart Avoid trimming at the front.
+ * @param ignoreEnd Avoid trimming at the end.
+ * @param noSplit Don't split up in middle of text node (No DOM change).
+ */
+ trim : function( ignoreStart, ignoreEnd, noSplit )
{
var startContainer = this.startContainer,
startOffset = this.startOffset,
@@ -736,7 +743,7 @@
}
// In other case, we split the text node and insert the new
// node at the split point.
- else
+ else if( !noSplit )
{
var nextText = startContainer.split( startOffset );
@@ -775,7 +782,7 @@
}
// In other case, we split the text node and insert the new
// node at the split point.
- else
+ else if ( !noSplit )
{
endContainer.split( endOffset );