| Index: third_party/WebKit/Source/core/editing/Editor.cpp
|
| diff --git a/third_party/WebKit/Source/core/editing/Editor.cpp b/third_party/WebKit/Source/core/editing/Editor.cpp
|
| index 5d0c85686a345b6edbb41d7c3b46bb40eaa3ee0f..928cb7c622eb4f1deb560d4df858c9de5e2d0e7d 100644
|
| --- a/third_party/WebKit/Source/core/editing/Editor.cpp
|
| +++ b/third_party/WebKit/Source/core/editing/Editor.cpp
|
| @@ -145,6 +145,25 @@ bool isInPasswordFieldWithUnrevealedPassword(const Position& position) {
|
| !input->shouldRevealPassword();
|
| }
|
|
|
| +EphemeralRange computeRangeForTranspose(LocalFrame& frame) {
|
| + const VisibleSelection& selection =
|
| + frame.selection().computeVisibleSelectionInDOMTree();
|
| + if (!selection.isCaret())
|
| + return EphemeralRange();
|
| +
|
| + // Make a selection that goes back one character and forward two characters.
|
| + const VisiblePosition& caret = selection.visibleStart();
|
| + const VisiblePosition& next =
|
| + isEndOfParagraph(caret) ? caret : nextPositionOf(caret);
|
| + const VisiblePosition& previous = previousPositionOf(next);
|
| + if (next.deepEquivalent() == previous.deepEquivalent())
|
| + return EphemeralRange();
|
| + const VisiblePosition& previousOfPrevious = previousPositionOf(previous);
|
| + if (!inSameParagraph(next, previousOfPrevious))
|
| + return EphemeralRange();
|
| + return makeRange(previousOfPrevious, next);
|
| +}
|
| +
|
| } // anonymous namespace
|
|
|
| Editor::RevealSelectionScope::RevealSelectionScope(Editor* editor)
|
| @@ -1380,41 +1399,24 @@ void Editor::transpose() {
|
| if (!canEdit())
|
| return;
|
|
|
| - VisibleSelection selection =
|
| - frame().selection().computeVisibleSelectionInDOMTreeDeprecated();
|
| - if (!selection.isCaret())
|
| - return;
|
| + // TODO(editing-dev): The use of updateStyleAndLayoutIgnorePendingStylesheets
|
| + // needs to be audited. see http://crbug.com/590369 for more details.
|
| + frame().document()->updateStyleAndLayoutIgnorePendingStylesheets();
|
|
|
| - // Make a selection that goes back one character and forward two characters.
|
| - VisiblePosition caret = selection.visibleStart();
|
| - VisiblePosition next =
|
| - isEndOfParagraph(caret) ? caret : nextPositionOf(caret);
|
| - VisiblePosition previous = previousPositionOf(next);
|
| - if (next.deepEquivalent() == previous.deepEquivalent())
|
| - return;
|
| - previous = previousPositionOf(previous);
|
| - if (!inSameParagraph(next, previous))
|
| - return;
|
| - const EphemeralRange range = makeRange(previous, next);
|
| + const EphemeralRange& range = computeRangeForTranspose(frame());
|
| if (range.isNull())
|
| return;
|
| - const SelectionInDOMTree newSelection =
|
| - SelectionInDOMTree::Builder().setBaseAndExtent(range).build();
|
|
|
| // Transpose the two characters.
|
| - String text = plainText(range);
|
| + const String& text = plainText(range);
|
| if (text.length() != 2)
|
| return;
|
| - String transposed = text.right(1) + text.left(1);
|
| -
|
| - // Select the two characters.
|
| - if (createVisibleSelection(newSelection) !=
|
| - frame().selection().computeVisibleSelectionInDOMTreeDeprecated())
|
| - frame().selection().setSelection(newSelection);
|
| + const String& transposed = text.right(1) + text.left(1);
|
|
|
| if (dispatchBeforeInputInsertText(
|
| eventTargetNodeForDocument(frame().document()), transposed,
|
| - InputEvent::InputType::InsertTranspose) !=
|
| + InputEvent::InputType::InsertTranspose,
|
| + new StaticRangeVector(1, StaticRange::create(range))) !=
|
| DispatchEventResult::NotCanceled)
|
| return;
|
|
|
| @@ -1426,8 +1428,27 @@ void Editor::transpose() {
|
| // needs to be audited. see http://crbug.com/590369 for more details.
|
| frame().document()->updateStyleAndLayoutIgnorePendingStylesheets();
|
|
|
| + // 'beforeinput' event handler may change selection, we need to re-calculate
|
| + // range.
|
| + const EphemeralRange& newRange = computeRangeForTranspose(frame());
|
| + if (newRange.isNull())
|
| + return;
|
| +
|
| + const String& newText = plainText(newRange);
|
| + if (newText.length() != 2)
|
| + return;
|
| + const String& newTransposed = newText.right(1) + newText.left(1);
|
| +
|
| + const SelectionInDOMTree& newSelection =
|
| + SelectionInDOMTree::Builder().setBaseAndExtent(newRange).build();
|
| +
|
| + // Select the two characters.
|
| + if (createVisibleSelection(newSelection) !=
|
| + frame().selection().computeVisibleSelectionInDOMTree())
|
| + frame().selection().setSelection(newSelection);
|
| +
|
| // Insert the transposed characters.
|
| - replaceSelectionWithText(transposed, false, false,
|
| + replaceSelectionWithText(newTransposed, false, false,
|
| InputEvent::InputType::InsertTranspose);
|
| }
|
|
|
|
|