OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2006, 2007, 2008, 2011 Apple Inc. All rights reserved. | 2 * Copyright (C) 2006, 2007, 2008, 2011 Apple Inc. All rights reserved. |
3 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) | 3 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) |
4 * | 4 * |
5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
6 * modification, are permitted provided that the following conditions | 6 * modification, are permitted provided that the following conditions |
7 * are met: | 7 * are met: |
8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
138 | 138 |
139 bool isInPasswordFieldWithUnrevealedPassword(const Position& position) { | 139 bool isInPasswordFieldWithUnrevealedPassword(const Position& position) { |
140 TextControlElement* textControl = enclosingTextControl(position); | 140 TextControlElement* textControl = enclosingTextControl(position); |
141 if (!isHTMLInputElement(textControl)) | 141 if (!isHTMLInputElement(textControl)) |
142 return false; | 142 return false; |
143 HTMLInputElement* input = toHTMLInputElement(textControl); | 143 HTMLInputElement* input = toHTMLInputElement(textControl); |
144 return (input->type() == InputTypeNames::password) && | 144 return (input->type() == InputTypeNames::password) && |
145 !input->shouldRevealPassword(); | 145 !input->shouldRevealPassword(); |
146 } | 146 } |
147 | 147 |
| 148 EphemeralRange computeRangeForTranspose(LocalFrame& frame) { |
| 149 const VisibleSelection& selection = |
| 150 frame.selection().computeVisibleSelectionInDOMTree(); |
| 151 if (!selection.isCaret()) |
| 152 return EphemeralRange(); |
| 153 |
| 154 // Make a selection that goes back one character and forward two characters. |
| 155 const VisiblePosition& caret = selection.visibleStart(); |
| 156 const VisiblePosition& next = |
| 157 isEndOfParagraph(caret) ? caret : nextPositionOf(caret); |
| 158 const VisiblePosition& previous = previousPositionOf(next); |
| 159 if (next.deepEquivalent() == previous.deepEquivalent()) |
| 160 return EphemeralRange(); |
| 161 const VisiblePosition& previousOfPrevious = previousPositionOf(previous); |
| 162 if (!inSameParagraph(next, previousOfPrevious)) |
| 163 return EphemeralRange(); |
| 164 return makeRange(previousOfPrevious, next); |
| 165 } |
| 166 |
148 } // anonymous namespace | 167 } // anonymous namespace |
149 | 168 |
150 Editor::RevealSelectionScope::RevealSelectionScope(Editor* editor) | 169 Editor::RevealSelectionScope::RevealSelectionScope(Editor* editor) |
151 : m_editor(editor) { | 170 : m_editor(editor) { |
152 ++m_editor->m_preventRevealSelection; | 171 ++m_editor->m_preventRevealSelection; |
153 } | 172 } |
154 | 173 |
155 Editor::RevealSelectionScope::~RevealSelectionScope() { | 174 Editor::RevealSelectionScope::~RevealSelectionScope() { |
156 DCHECK(m_editor->m_preventRevealSelection); | 175 DCHECK(m_editor->m_preventRevealSelection); |
157 --m_editor->m_preventRevealSelection; | 176 --m_editor->m_preventRevealSelection; |
(...skipping 1215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1373 return; | 1392 return; |
1374 if (!frame().selection().isAvailable()) | 1393 if (!frame().selection().isAvailable()) |
1375 return; | 1394 return; |
1376 frame().selection().revealSelection(alignment, revealExtentOption); | 1395 frame().selection().revealSelection(alignment, revealExtentOption); |
1377 } | 1396 } |
1378 | 1397 |
1379 void Editor::transpose() { | 1398 void Editor::transpose() { |
1380 if (!canEdit()) | 1399 if (!canEdit()) |
1381 return; | 1400 return; |
1382 | 1401 |
1383 VisibleSelection selection = | 1402 // TODO(editing-dev): The use of updateStyleAndLayoutIgnorePendingStylesheets |
1384 frame().selection().computeVisibleSelectionInDOMTreeDeprecated(); | 1403 // needs to be audited. see http://crbug.com/590369 for more details. |
1385 if (!selection.isCaret()) | 1404 frame().document()->updateStyleAndLayoutIgnorePendingStylesheets(); |
| 1405 |
| 1406 const EphemeralRange& range = computeRangeForTranspose(frame()); |
| 1407 if (range.isNull()) |
1386 return; | 1408 return; |
1387 | 1409 |
1388 // Make a selection that goes back one character and forward two characters. | |
1389 VisiblePosition caret = selection.visibleStart(); | |
1390 VisiblePosition next = | |
1391 isEndOfParagraph(caret) ? caret : nextPositionOf(caret); | |
1392 VisiblePosition previous = previousPositionOf(next); | |
1393 if (next.deepEquivalent() == previous.deepEquivalent()) | |
1394 return; | |
1395 previous = previousPositionOf(previous); | |
1396 if (!inSameParagraph(next, previous)) | |
1397 return; | |
1398 const EphemeralRange range = makeRange(previous, next); | |
1399 if (range.isNull()) | |
1400 return; | |
1401 const SelectionInDOMTree newSelection = | |
1402 SelectionInDOMTree::Builder().setBaseAndExtent(range).build(); | |
1403 | |
1404 // Transpose the two characters. | 1410 // Transpose the two characters. |
1405 String text = plainText(range); | 1411 const String& text = plainText(range); |
1406 if (text.length() != 2) | 1412 if (text.length() != 2) |
1407 return; | 1413 return; |
1408 String transposed = text.right(1) + text.left(1); | 1414 const String& transposed = text.right(1) + text.left(1); |
1409 | |
1410 // Select the two characters. | |
1411 if (createVisibleSelection(newSelection) != | |
1412 frame().selection().computeVisibleSelectionInDOMTreeDeprecated()) | |
1413 frame().selection().setSelection(newSelection); | |
1414 | 1415 |
1415 if (dispatchBeforeInputInsertText( | 1416 if (dispatchBeforeInputInsertText( |
1416 eventTargetNodeForDocument(frame().document()), transposed, | 1417 eventTargetNodeForDocument(frame().document()), transposed, |
1417 InputEvent::InputType::InsertTranspose) != | 1418 InputEvent::InputType::InsertTranspose, |
| 1419 new StaticRangeVector(1, StaticRange::create(range))) != |
1418 DispatchEventResult::NotCanceled) | 1420 DispatchEventResult::NotCanceled) |
1419 return; | 1421 return; |
1420 | 1422 |
1421 // 'beforeinput' event handler may destroy document. | 1423 // 'beforeinput' event handler may destroy document. |
1422 if (m_frame->document()->frame() != m_frame) | 1424 if (m_frame->document()->frame() != m_frame) |
1423 return; | 1425 return; |
1424 | 1426 |
1425 // TODO(editing-dev): The use of updateStyleAndLayoutIgnorePendingStylesheets | 1427 // TODO(editing-dev): The use of updateStyleAndLayoutIgnorePendingStylesheets |
1426 // needs to be audited. see http://crbug.com/590369 for more details. | 1428 // needs to be audited. see http://crbug.com/590369 for more details. |
1427 frame().document()->updateStyleAndLayoutIgnorePendingStylesheets(); | 1429 frame().document()->updateStyleAndLayoutIgnorePendingStylesheets(); |
1428 | 1430 |
| 1431 // 'beforeinput' event handler may change selection, we need to re-calculate |
| 1432 // range. |
| 1433 const EphemeralRange& newRange = computeRangeForTranspose(frame()); |
| 1434 if (newRange.isNull()) |
| 1435 return; |
| 1436 |
| 1437 const String& newText = plainText(newRange); |
| 1438 if (newText.length() != 2) |
| 1439 return; |
| 1440 const String& newTransposed = newText.right(1) + newText.left(1); |
| 1441 |
| 1442 const SelectionInDOMTree& newSelection = |
| 1443 SelectionInDOMTree::Builder().setBaseAndExtent(newRange).build(); |
| 1444 |
| 1445 // Select the two characters. |
| 1446 if (createVisibleSelection(newSelection) != |
| 1447 frame().selection().computeVisibleSelectionInDOMTree()) |
| 1448 frame().selection().setSelection(newSelection); |
| 1449 |
1429 // Insert the transposed characters. | 1450 // Insert the transposed characters. |
1430 replaceSelectionWithText(transposed, false, false, | 1451 replaceSelectionWithText(newTransposed, false, false, |
1431 InputEvent::InputType::InsertTranspose); | 1452 InputEvent::InputType::InsertTranspose); |
1432 } | 1453 } |
1433 | 1454 |
1434 void Editor::addToKillRing(const EphemeralRange& range) { | 1455 void Editor::addToKillRing(const EphemeralRange& range) { |
1435 if (m_shouldStartNewKillRingSequence) | 1456 if (m_shouldStartNewKillRingSequence) |
1436 killRing().startNewSequence(); | 1457 killRing().startNewSequence(); |
1437 | 1458 |
1438 DCHECK(!frame().document()->needsLayoutTreeUpdate()); | 1459 DCHECK(!frame().document()->needsLayoutTreeUpdate()); |
1439 String text = plainText(range); | 1460 String text = plainText(range); |
1440 killRing().append(text); | 1461 killRing().append(text); |
(...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1795 | 1816 |
1796 DEFINE_TRACE(Editor) { | 1817 DEFINE_TRACE(Editor) { |
1797 visitor->trace(m_frame); | 1818 visitor->trace(m_frame); |
1798 visitor->trace(m_lastEditCommand); | 1819 visitor->trace(m_lastEditCommand); |
1799 visitor->trace(m_undoStack); | 1820 visitor->trace(m_undoStack); |
1800 visitor->trace(m_mark); | 1821 visitor->trace(m_mark); |
1801 visitor->trace(m_typingStyle); | 1822 visitor->trace(m_typingStyle); |
1802 } | 1823 } |
1803 | 1824 |
1804 } // namespace blink | 1825 } // namespace blink |
OLD | NEW |