Commit 11d5f361 authored by Xiaocheng Hu's avatar Xiaocheng Hu Committed by Commit Bot

[Spellchecker] Handles nested editables correctly in cold mode checker

When the currently focused editable element is nested in an uneditable
element (see the new layout test in this CL as an example), cold mode
spellchecker may create invalid checking ranges:
- the range starts at the end position of the last sentence
- the range ends at the last position in the focused editable element
- when the editable element is nested in uneditable element, a reversed
  range is created

This patch fixes the issue by using the highest root editable as the
element to check, so that all sentences are within the element.

To ensure that uneditable nodes in the highest root are not marked, this
patch also modifies SpellChecker::IsSpellCheckingEnabledAt() to return
false on uneditable nodes.

Bug: 848026
Change-Id: I26d9852ffc66aad150cf3856fd402fc31e3ad3a0
Reviewed-on: https://chromium-review.googlesource.com/1080215Reviewed-by: default avatarYoshifumi Inoue <yosin@chromium.org>
Commit-Queue: Xiaocheng Hu <xiaochengh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#563159}
parent e88aa42e
<!doctype html>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<script src="../assert_selection.js"></script>
<script src="spellcheck_test.js"></script>
<script>
const longCorrectText = ' word '.repeat(20);
// crbug.com/848026
spellcheck_test(
[
`<div contenteditable>${longCorrectText}`,
'<span contenteditable="false">zz ',
'<span contenteditable id="target">zz</span>',
' zz</span>',
`${longCorrectText}</div>`
].join(''),
document => document.getElementById('target').focus(),
[
`<div contenteditable>${longCorrectText}`,
'<span contenteditable="false">zz ',
'<span contenteditable id="target">#zz#</span>',
' zz</span>',
`${longCorrectText}</div>`
].join(''),
{
title: 'Cold mode checks text in nested editables correctly without crashing',
needsFullCheck: true
}
);
</script>
...@@ -63,10 +63,11 @@ const Element* ColdModeSpellCheckRequester::CurrentFocusedEditable() const { ...@@ -63,10 +63,11 @@ const Element* ColdModeSpellCheckRequester::CurrentFocusedEditable() const {
if (position.IsNull()) if (position.IsNull())
return nullptr; return nullptr;
const Element* element = RootEditableElementOf(position); const ContainerNode* root = HighestEditableRoot(position);
if (!element || !element->isConnected()) if (!root || !root->isConnected() || !root->IsElementNode())
return nullptr; return nullptr;
const Element* element = ToElement(root);
if (!element->IsSpellCheckingEnabled() || if (!element->IsSpellCheckingEnabled() ||
!SpellChecker::IsSpellCheckingEnabledAt(position)) !SpellChecker::IsSpellCheckingEnabledAt(position))
return nullptr; return nullptr;
......
...@@ -783,7 +783,8 @@ bool SpellChecker::IsSpellCheckingEnabledAt(const Position& position) { ...@@ -783,7 +783,8 @@ bool SpellChecker::IsSpellCheckingEnabledAt(const Position& position) {
} }
HTMLElement* element = HTMLElement* element =
Traversal<HTMLElement>::FirstAncestorOrSelf(*position.AnchorNode()); Traversal<HTMLElement>::FirstAncestorOrSelf(*position.AnchorNode());
return element && element->IsSpellCheckingEnabled(); return element && element->IsSpellCheckingEnabled() &&
HasEditableStyle(*element);
} }
STATIC_ASSERT_ENUM(kWebTextDecorationTypeSpelling, kTextDecorationTypeSpelling); STATIC_ASSERT_ENUM(kWebTextDecorationTypeSpelling, kTextDecorationTypeSpelling);
......
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