Skip to content

Commit

Permalink
Merge branch 't/13062' into major
Browse files Browse the repository at this point in the history
  • Loading branch information
Tade0 committed Mar 1, 2017
2 parents a3b2b66 + 8215af9 commit 7ee2b8a
Show file tree
Hide file tree
Showing 7 changed files with 140 additions and 10 deletions.
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ New Features:

Fixed Issues:

* [#13062](http://dev.ckeditor.com/ticket/13062): Fixed: Impossible to unlink when the caret is at the edge of the link.
* [#13585](http://dev.ckeditor.com/ticket/13585): Fixed: Error when wrapping two adjacent `<div>`s with a `<div>`.
* [#16866](http://dev.ckeditor.com/ticket/16866): [IE, Edge] Fixed: Whitespaces not preserved when pasting from Word.
* [#16860](http://dev.ckeditor.com/ticket/16860): Fixed: Paragraphs which only look like lists wrongly transformed into them when pasting from Word.
Expand Down
21 changes: 13 additions & 8 deletions core/style.js
Original file line number Diff line number Diff line change
Expand Up @@ -1058,27 +1058,31 @@ CKEDITOR.STYLE_OBJECT = 3;
range.enlarge( CKEDITOR.ENLARGE_INLINE, 1 );

var bookmark = range.createBookmark(),
startNode = bookmark.startNode;
startNode = bookmark.startNode,
alwaysRemoveElement = this._.definition.alwaysRemoveElement;

if ( range.collapsed ) {
var startPath = new CKEDITOR.dom.elementPath( startNode.getParent(), range.root ),
// The topmost element in elementspatch which we should jump out of.
// The topmost element in elements path which we should jump out of.
boundaryElement;


for ( var i = 0, element; i < startPath.elements.length && ( element = startPath.elements[ i ] ); i++ ) {
// 1. If it's collaped inside text nodes, try to remove the style from the whole element.
//
// 2. Otherwise if it's collapsed on element boundaries, moving the selection
// outside the styles instead of removing the whole tag,
// also make sure other inner styles were well preserverd.(#3309)
if ( element == startPath.block || element == startPath.blockLimit )
// also make sure other inner styles were well preserved.(#3309)
//
// 3. Force removing the element even if it's an boundary element when alwaysRemoveElement is true.
// Without it, the links won't be unlinked if the cursor is placed right before/after it. (#13062)
if ( element == startPath.block || element == startPath.blockLimit ) {
break;
}

if ( this.checkElementRemovable( element ) ) {
var isStart;

if ( range.collapsed && ( range.checkBoundaryOfElement( element, CKEDITOR.END ) || ( isStart = range.checkBoundaryOfElement( element, CKEDITOR.START ) ) ) ) {
if ( !alwaysRemoveElement && range.collapsed && ( range.checkBoundaryOfElement( element, CKEDITOR.END ) || ( isStart = range.checkBoundaryOfElement( element, CKEDITOR.START ) ) ) ) {
boundaryElement = element;
boundaryElement.match = isStart ? 'start' : 'end';
} else {
Expand All @@ -1087,10 +1091,11 @@ CKEDITOR.STYLE_OBJECT = 3;
// no difference that they're separate entities in the DOM tree. So, merge
// them before removal.
element.mergeSiblings();
if ( element.is( this.element ) )
if ( element.is( this.element ) ) {
removeFromElement.call( this, element );
else
} else {
removeOverrides( element, getOverrides( this )[ element.getName() ] );
}
}
}
}
Expand Down
24 changes: 23 additions & 1 deletion plugins/link/plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -752,8 +752,29 @@
CKEDITOR.unlinkCommand = function() {};
CKEDITOR.unlinkCommand.prototype = {
exec: function( editor ) {
// IE/Edge removes link from selection while executing "unlink" command when cursor
// is right before/after link's text. Therefore whole link must be selected and the
// position of cursor must be restored to its initial state after unlinking. (#13062)
if ( CKEDITOR.env.ie ) {
var range = editor.getSelection().getRanges()[ 0 ],
link = ( range.getPreviousEditableNode() && range.getPreviousEditableNode().getAscendant( 'a', true ) ) ||
( range.getNextEditableNode() && range.getNextEditableNode().getAscendant( 'a', true ) ),
bookmark;

if ( range.collapsed && link ) {
bookmark = range.createBookmark();
range.selectNodeContents( link );
range.select();
}
}

var style = new CKEDITOR.style( { element: 'a', type: CKEDITOR.STYLE_INLINE, alwaysRemoveElement: 1 } );
editor.removeStyle( style );

if ( bookmark ) {
range.moveToBookmark( bookmark );
range.select();
}
},

refresh: function( editor, path ) {
Expand All @@ -770,7 +791,8 @@

contextSensitive: 1,
startDisabled: 1,
requiredContent: 'a[href]'
requiredContent: 'a[href]',
editorFocus: 1
};

CKEDITOR.removeAnchorCommand = function() {};
Expand Down
15 changes: 15 additions & 0 deletions tests/core/style/applyremove.js
Original file line number Diff line number Diff line change
Expand Up @@ -537,6 +537,21 @@
fixHtml( getInnerHtml( ct ).replace( /rgb\(255,255,0\)/g, 'rgb(255, 255, 0)' ) ) );
},

// #13062
'test forcing remove of boundary element': function() {
var editor = this.editor,
bot = this.editorBot,
style = new CKEDITOR.style( { element: 'b', type: CKEDITOR.STYLE_INLINE, alwaysRemoveElement: 1 } );

bot.setHtmlWithSelection( '<p><b>^example</b></p>' );
editor.removeStyle( style );
assert.areSame( '<p>^example</p>', bot.htmlWithSelection() );

bot.setHtmlWithSelection( '<p><b>example^</b></p>' );
editor.removeStyle( style );
assert.areSame( '<p>example^</p>', bot.htmlWithSelection() );
},

'test filler is preserved when applying block style': function() {
if ( !CKEDITOR.env.needsBrFiller )
assert.ignore();
Expand Down
47 changes: 46 additions & 1 deletion tests/plugins/link/link.js
Original file line number Diff line number Diff line change
Expand Up @@ -475,13 +475,58 @@
} );
},

'test CKEDITOR.link.showDisplayTextForElement': function(){
'test CKEDITOR.link.showDisplayTextForElement': function() {
var doc = CKEDITOR.document,
showDisplayTextForElement = CKEDITOR.plugins.link.showDisplayTextForElement;

assert.isFalse( showDisplayTextForElement( doc.findOne( 'input#blurTarget' ), this.editor ), 'Input element' );
assert.isTrue( showDisplayTextForElement( doc.findOne( 'span' ), this.editor ), 'Span element' );
assert.isTrue( showDisplayTextForElement( null, this.editor ), 'Null value' );
},

// #13062
'test unlink when cursor is right before the link': function() {
var editor = this.editor,
bot = this.editorBot;

bot.setHtmlWithSelection( '<p><a href="http://cksource.com">^Link</a></p>' );

editor.ui.get( 'Unlink' ).click( editor );

assert.areSame( '<p>^Link</p>', bot.htmlWithSelection() );
},

// #13062
'test unlink when cursor is right after the link': function() {
// IE8 fails this test for unknown reason; however it does well
// in the manual one.
if ( CKEDITOR.env.ie && CKEDITOR.env.version == 8 ) {
assert.ignore();
}

var editor = this.editor,
bot = this.editorBot;

bot.setHtmlWithSelection( '<p><a href="http://cksource.com">Link^</a></p>' );

resume( function() {
editor.ui.get( 'Unlink' ).click( editor );
assert.areSame( '<p>Link^</p>', bot.htmlWithSelection() );
} );

wait( 100 );
},

// #13062
'test unlink when cursor is right before the link and there are more than one link in paragraph': function() {
var editor = this.editor,
bot = this.editorBot;

bot.setHtmlWithSelection( '<p>I am<a href="http://foo"> an </a>in<a href="http://bar">sta</a>nce of <a href="http://ckeditor.com">^<s>CKEditor</s></a>.</p>' );

editor.ui.get( 'Unlink' ).click( editor );

assert.areSame( '<p>I am<a href="http://foo"> an </a>in<a href="http://bar">sta</a>nce of ^<s>CKEditor</s>.</p>', bot.htmlWithSelection() );
}
} );
} )();
11 changes: 11 additions & 0 deletions tests/plugins/link/manual/unlinkbeforeafterlink.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<body>
<div id="editor">
<p><a href="http://cksource.com">Link 1</a></p>
<p><a href="http://cksource.com">Link 2</a></p>
<p>I'm<a href="http://foo"> an </a>in<a href="http://bar">sta</a>nce of <a href="http://ckeditor.com"><s>CKEditor</s></a>.</p>
</div>

<script>
CKEDITOR.replace( 'editor' , { extraAllowedContent: 's' } );
</script>
</body>
31 changes: 31 additions & 0 deletions tests/plugins/link/manual/unlinkbeforeafterlink.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
@bender-tags: tc, link, editor, 13062, 4.7.0
@bender-ui: collapsed
@bender-ckeditor-plugins: link, toolbar, elementspath, wysiwygarea

----

1. Place the cursor just before the link's text in first paragraph (check in element's path that you're still inside the link).
2. Click the unlink button.

**Expected:**
* The link is removed.

---

1. Place the cursor just after the link's text in second paragraph (check in element's path that you're still inside the link).
2. Click the unlink button.

**Expected:**
* The link is removed.

---

1. Place the cursor just after the last link's text in third paragraph (check in element's path that you're still inside the link).
2. Click the unlink button.

**Expected:**
* The link is removed.

**Unexpected:**
* All links in paragraph are removed.
* Strikethrough is removed.

0 comments on commit 7ee2b8a

Please sign in to comment.