Commit 742c6a48 authored by Anupam Snigdha's avatar Anupam Snigdha Committed by Commit Bot

Fix hyperlink delete when replaced with a character.

When the hyperlink is entirely selected, currently we do not remove
the hyperlink, but rather do a replaceData operation in
|SetCharacterDataCommand::DoApply| to insert the character that the
user has typed into the hyperlink and the subsequent characters are
inserted outside the hyperlink. This change deletes the hyperlink
when user selects the entire hyperlink and types a single character.
However, we do not replace the hyperlink if insertText operation
inserts a text (more than one character) into the hyperlink when the
entire link's content is selected.

Test: web_tests/editing/execCommand/insert_text_hyperlink_replace.html

Bug: 848506

Change-Id: Ied50697792f8d496ce59792129f5947f782da5e1
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2545686Reviewed-by: default avatarYoshifumi Inoue <yosin@chromium.org>
Commit-Queue: Anupam Snigdha <snianu@microsoft.com>
Cr-Commit-Position: refs/heads/master@{#828592}
parent b6b96a60
...@@ -104,7 +104,23 @@ bool InsertTextCommand::PerformTrivialReplace(const String& text) { ...@@ -104,7 +104,23 @@ bool InsertTextCommand::PerformTrivialReplace(const String& text) {
if (text.Contains('\t') || text.Contains(' ') || text.Contains('\n')) if (text.Contains('\t') || text.Contains(' ') || text.Contains('\n'))
return false; return false;
// Also if the text is surrounded by a hyperlink and all the contents of the
// link are selected, then we shouldn't be retaining the link with just one
// character because the user wouldn't be able to edit the link if it has only
// one character.
Position start = EndingVisibleSelection().Start(); Position start = EndingVisibleSelection().Start();
Element* enclosing_anchor = EnclosingAnchorElement(start);
if (enclosing_anchor && text.length() <= 1) {
VisiblePosition first_in_anchor =
VisiblePosition::FirstPositionInNode(*enclosing_anchor);
VisiblePosition last_in_anchor =
VisiblePosition::LastPositionInNode(*enclosing_anchor);
Position end = EndingVisibleSelection().End();
if (first_in_anchor.DeepEquivalent() == start &&
last_in_anchor.DeepEquivalent() == end)
return false;
}
Position end_position = ReplaceSelectedTextInNode(text); Position end_position = ReplaceSelectedTextInNode(text);
if (end_position.IsNull()) if (end_position.IsNull())
return false; return false;
......
...@@ -297,9 +297,8 @@ TEST_F(InsertTextCommandTest, AnchorElementWithBlockCrash) { ...@@ -297,9 +297,8 @@ TEST_F(InsertTextCommandTest, AnchorElementWithBlockCrash) {
// Crash happens here with when '\n' is inserted. // Crash happens here with when '\n' is inserted.
GetDocument().execCommand("inserttext", false, "a\n", ASSERT_NO_EXCEPTION); GetDocument().execCommand("inserttext", false, "a\n", ASSERT_NO_EXCEPTION);
EXPECT_EQ( EXPECT_EQ(
"<i style=\"display: block;\">" "<a href=\"www\" style=\"display:block\"><i>a</i></a><a href=\"www\" "
"<a href=\"www\" style=\"display: block;\">a</a>" "style=\"display:block\"><i>|<br></i></a>",
"</i>|",
GetSelectionTextFromBody()); GetSelectionTextFromBody());
} }
......
<!doctype html>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<script src="../assert_selection.js"></script>
<script>
selection_test(
[
'<div contenteditable>',
'<a href="#">^test|</a>',
'</div>',
],
'insertText c',
[
'<div contenteditable>',
'c|',
'</div>',
],
'InsertText replacing the hyperlink');
selection_test(
[
'<div contenteditable>',
'<a href="#">^test|</a>',
'</div>',
],
'insertText new',
[
'<div contenteditable>',
'<a href="#">new|</a>',
'</div>',
],
'InsertText not replacing the hyperlink');
selection_test(
[
'<div contenteditable>',
'<a href="#">t^es|t</a>',
'</div>',
],
'insertText c',
[
'<div contenteditable>',
'<a href="#">tc|t</a>',
'</div>',
],
'InsertText replacing content inside the hyperlink');
selection_test(
[
'<div contenteditable>^',
'<a href="#">test</a>|',
'</div>',
],
'insertText c',
[
'<div contenteditable>',
'c|',
'</div>',
],
'InsertText replacing content inside the editable block');
selection_test(
[
'<div contenteditable>',
'<a href="#">test|</a>',
'</div>',
],
'insertText c',
[
'<div contenteditable>',
'<a href="#">test</a>c|',
'</div>',
],
'InsertText after hyperlink');
selection_test(
[
'<div contenteditable>',
'<a href="#">|test</a>',
'</div>',
],
'insertText c',
[
'<div contenteditable>',
'c|<a href="#">test</a>',
'</div>',
],
'InsertText before hyperlink');
selection_test(
[
'<div contenteditable>',
'<a href="#"><i>^test|</i></a>',
'</div>',
],
'insertText c',
[
'<div contenteditable>',
'<i>c|</i>',
'</div>',
],
'InsertText replacing the hyperlink where text is wrapped inside inline');
selection_test(
[
'<div contenteditable>',
'<a href="#"><i>t^est|</i></a>',
'</div>',
],
'insertText \t',
[
'<div contenteditable>',
'<i><a href="#">t<span style="white-space:pre">\t|</span></a></i>',
'</div>',
],
'InsertText tab not replacing the hyperlink where text is wrapped inside inline');
</script>
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment