Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(808)

Unified Diff: Source/core/editing/InputMethodController.cpp

Issue 1330233003: Revert of Avoid style clobbering in setCompositionFromExistingText. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Source/core/editing/InputMethodController.h ('k') | Source/core/editing/markers/DocumentMarker.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/core/editing/InputMethodController.cpp
diff --git a/Source/core/editing/InputMethodController.cpp b/Source/core/editing/InputMethodController.cpp
index f1d4018dbf735e082b90f8c3fc7339dfd64f377c..3c695f1e8270c7f1baf763f8e3825d031e9a2993 100644
--- a/Source/core/editing/InputMethodController.cpp
+++ b/Source/core/editing/InputMethodController.cpp
@@ -29,17 +29,15 @@
#include "core/dom/Document.h"
#include "core/dom/Element.h"
+#include "core/dom/Range.h"
#include "core/dom/Text.h"
-#include "core/editing/EditingUtilities.h"
#include "core/editing/Editor.h"
#include "core/editing/commands/TypingCommand.h"
-#include "core/editing/markers/DocumentMarkerController.h"
#include "core/events/CompositionEvent.h"
#include "core/frame/LocalFrame.h"
#include "core/html/HTMLTextAreaElement.h"
#include "core/input/EventHandler.h"
#include "core/layout/LayoutObject.h"
-#include "core/layout/LayoutTheme.h"
#include "core/page/ChromeClient.h"
namespace blink {
@@ -64,8 +62,8 @@
InputMethodController::InputMethodController(LocalFrame& frame)
: m_frame(&frame)
- , m_isDirty(false)
- , m_hasComposition(false)
+ , m_compositionStart(0)
+ , m_compositionEnd(0)
{
}
@@ -75,7 +73,7 @@
bool InputMethodController::hasComposition() const
{
- return m_hasComposition;
+ return m_compositionNode && m_compositionNode->isContentEditable();
}
inline Editor& InputMethodController::editor() const
@@ -85,13 +83,8 @@
void InputMethodController::clear()
{
- m_hasComposition = false;
- if (m_compositionRange) {
- m_compositionRange->setStart(frame().document(), 0);
- m_compositionRange->collapse(true);
- }
- frame().document()->markers().removeMarkers(DocumentMarker::Composition);
- m_isDirty = false;
+ m_compositionNode = nullptr;
+ m_customCompositionUnderlines.clear();
}
bool InputMethodController::insertTextForConfirmedComposition(const String& text)
@@ -116,7 +109,7 @@
{
if (!hasComposition())
return false;
- return confirmComposition(plainText(compositionEphemeralRange()));
+ return finishComposition(m_compositionNode->data().substring(m_compositionStart, m_compositionEnd - m_compositionStart), ConfirmComposition);
}
bool InputMethodController::confirmComposition(const String& text)
@@ -156,14 +149,13 @@
return;
// Check if selection start and selection end are valid.
- FrameSelection& selection = frame().selection();
- if (!selection.isNone() && !m_compositionRange->collapsed()) {
- Position start = selection.start();
- Position end = selection.end();
- if (selection.start().compareTo(m_compositionRange->startPosition()) >= 0
- && selection.end().compareTo(m_compositionRange->endPosition()) <= 0)
- return;
- }
+ Position start = frame().selection().start();
+ Position end = frame().selection().end();
+ if (start.computeContainerNode() == m_compositionNode
+ && end.computeContainerNode() == m_compositionNode
+ && static_cast<unsigned>(start.computeOffsetInContainerNode()) >= m_compositionStart
+ && static_cast<unsigned>(end.computeOffsetInContainerNode()) <= m_compositionEnd)
+ return;
cancelComposition();
frame().chromeClient().didCancelCompositionOnSelectionChange();
@@ -194,19 +186,17 @@
target->dispatchEvent(event);
}
- bool dirty = m_isDirty || plainText(compositionEphemeralRange()) != text;
-
// If text is empty, then delete the old composition here. If text is non-empty, InsertTextCommand::input
// will delete the old composition with an optimized replace operation.
- if (text.isEmpty() && mode != CancelComposition && dirty) {
+ if (text.isEmpty() && mode != CancelComposition) {
ASSERT(frame().document());
TypingCommand::deleteSelection(*frame().document(), 0);
}
- clear();
-
- if (dirty)
- insertTextForConfirmedComposition(text);
+ m_compositionNode = nullptr;
+ m_customCompositionUnderlines.clear();
+
+ insertTextForConfirmedComposition(text);
if (mode == CancelComposition) {
// An open typing command that disagrees about current selection would cause issues with typing later on.
@@ -237,15 +227,15 @@
// 1. Starting a new composition.
// Send a compositionstart and a compositionupdate event when this function creates
// a new composition node, i.e.
- // !hasComposition() && !text.isEmpty().
+ // m_compositionNode == 0 && !text.isEmpty().
// Sending a compositionupdate event at this time ensures that at least one
// compositionupdate event is dispatched.
// 2. Updating the existing composition node.
// Send a compositionupdate event when this function updates the existing composition
- // node, i.e. hasComposition() && !text.isEmpty().
+ // node, i.e. m_compositionNode != 0 && !text.isEmpty().
// 3. Canceling the ongoing composition.
// Send a compositionend event when function deletes the existing composition node, i.e.
- // !hasComposition() && test.isEmpty().
+ // m_compositionNode != 0 && test.isEmpty().
RefPtrWillBeRawPtr<CompositionEvent> event = nullptr;
if (!hasComposition()) {
// We should send a compositionstart event only when the given text is not empty because this
@@ -271,7 +261,8 @@
TypingCommand::deleteSelection(*frame().document(), TypingCommand::PreventSpellChecking);
}
- clear();
+ m_compositionNode = nullptr;
+ m_customCompositionUnderlines.clear();
if (text.isEmpty())
return;
@@ -294,13 +285,14 @@
if (baseOffset + text.length() != extentOffset)
return;
- m_isDirty = true;
- m_hasComposition = true;
- if (!m_compositionRange)
- m_compositionRange = Range::create(baseNode->document());
- m_compositionRange->setStart(baseNode, baseOffset);
- m_compositionRange->setEnd(baseNode, extentOffset);
-
+ m_compositionNode = toText(baseNode);
+ m_compositionStart = baseOffset;
+ m_compositionEnd = extentOffset;
+ m_customCompositionUnderlines = underlines;
+ for (auto& underline : m_customCompositionUnderlines) {
+ underline.startOffset += baseOffset;
+ underline.endOffset += baseOffset;
+ }
if (baseNode->layoutObject())
baseNode->layoutObject()->setShouldDoFullPaintInvalidation();
@@ -308,67 +300,61 @@
unsigned end = std::min(std::max(start, baseOffset + selectionEnd), extentOffset);
RefPtrWillBeRawPtr<Range> selectedRange = Range::create(baseNode->document(), baseNode, start, baseNode, end);
frame().selection().setSelectedRange(selectedRange.get(), TextAffinity::Downstream, FrameSelection::NonDirectional, NotUserTriggered);
-
- if (underlines.isEmpty()) {
- frame().document()->markers().addCompositionMarker(m_compositionRange->startPosition(), m_compositionRange->endPosition(), Color::black, false, LayoutTheme::theme().platformDefaultCompositionBackgroundColor());
- return;
- }
- for (const auto& underline : underlines) {
- unsigned underlineStart = baseOffset + underline.startOffset;
- unsigned underlineEnd = baseOffset + underline.endOffset;
- EphemeralRange ephemeralLineRange = EphemeralRange(Position(baseNode, underlineStart), Position(baseNode, underlineEnd));
- if (ephemeralLineRange.isNull())
- continue;
- frame().document()->markers().addCompositionMarker(ephemeralLineRange.startPosition(), ephemeralLineRange.endPosition(), underline.color, underline.thick, underline.backgroundColor);
- }
}
void InputMethodController::setCompositionFromExistingText(const Vector<CompositionUnderline>& underlines, unsigned compositionStart, unsigned compositionEnd)
{
Element* editable = frame().selection().rootEditableElement();
- if (!editable)
- return;
-
- const EphemeralRange range = PlainTextRange(compositionStart, compositionEnd).createRange(*editable);
- if (range.isNull())
- return;
-
- const Position start = range.startPosition();
- if (editableRootForPosition(start) != editable)
- return;
-
- const Position end = range.endPosition();
- if (editableRootForPosition(end) != editable)
- return;
-
- clear();
-
- for (const auto& underline : underlines) {
- unsigned underlineStart = compositionStart + underline.startOffset;
- unsigned underlineEnd = compositionStart + underline.endOffset;
- EphemeralRange ephemeralLineRange = PlainTextRange(underlineStart, underlineEnd).createRange(*editable);
- if (ephemeralLineRange.isNull())
- continue;
- frame().document()->markers().addCompositionMarker(ephemeralLineRange.startPosition(), ephemeralLineRange.endPosition(), underline.color, underline.thick, underline.backgroundColor);
- }
-
- m_hasComposition = true;
- if (!m_compositionRange)
- m_compositionRange = Range::create(range.document());
- m_compositionRange->setStart(range.startPosition());
- m_compositionRange->setEnd(range.endPosition());
+ Position base = mostForwardCaretPosition(frame().selection().base());
+ Node* baseNode = base.anchorNode();
+ if (baseNode && editable->firstChild() == baseNode && editable->lastChild() == baseNode && baseNode->isTextNode()) {
+ m_compositionNode = nullptr;
+ m_customCompositionUnderlines.clear();
+
+ if (!base.isOffsetInAnchor())
+ return;
+ if (baseNode != frame().selection().extent().anchorNode())
+ return;
+
+ m_compositionNode = toText(baseNode);
+ const EphemeralRange range = PlainTextRange(compositionStart, compositionEnd).createRange(*editable);
+ if (range.isNull())
+ return;
+
+ m_compositionStart = range.startPosition().computeOffsetInContainerNode();
+ m_compositionEnd = range.endPosition().computeOffsetInContainerNode();
+ m_customCompositionUnderlines = underlines;
+ size_t numUnderlines = m_customCompositionUnderlines.size();
+ for (size_t i = 0; i < numUnderlines; ++i) {
+ m_customCompositionUnderlines[i].startOffset += m_compositionStart;
+ m_customCompositionUnderlines[i].endOffset += m_compositionStart;
+ }
+ if (baseNode->layoutObject())
+ baseNode->layoutObject()->setShouldDoFullPaintInvalidation();
+ return;
+ }
+
+ Editor::RevealSelectionScope revealSelectionScope(&editor());
+ SelectionOffsetsScope selectionOffsetsScope(this);
+ setSelectionOffsets(PlainTextRange(compositionStart, compositionEnd));
+ setComposition(frame().selectedText(), underlines, 0, 0);
}
EphemeralRange InputMethodController::compositionEphemeralRange() const
{
if (!hasComposition())
return EphemeralRange();
- return EphemeralRange(m_compositionRange.get());
+ unsigned length = m_compositionNode->length();
+ unsigned start = std::min(m_compositionStart, length);
+ unsigned end = std::min(std::max(start, m_compositionEnd), length);
+ if (start >= end)
+ return EphemeralRange();
+ return EphemeralRange(Position(m_compositionNode.get(), start), Position(m_compositionNode.get(), end));
}
PassRefPtrWillBeRawPtr<Range> InputMethodController::compositionRange() const
{
- return hasComposition() ? m_compositionRange : nullptr;
+ return createRange(compositionEphemeralRange());
}
PlainTextRange InputMethodController::getSelectionOffsets() const
@@ -436,7 +422,7 @@
DEFINE_TRACE(InputMethodController)
{
visitor->trace(m_frame);
- visitor->trace(m_compositionRange);
+ visitor->trace(m_compositionNode);
}
} // namespace blink
« no previous file with comments | « Source/core/editing/InputMethodController.h ('k') | Source/core/editing/markers/DocumentMarker.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698