Chromium Code Reviews| Index: Source/core/editing/GranularityStrategy.cpp |
| diff --git a/Source/core/editing/GranularityStrategy.cpp b/Source/core/editing/GranularityStrategy.cpp |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..c1ef834442333ad684da01c1f3959b9fa299e18c |
| --- /dev/null |
| +++ b/Source/core/editing/GranularityStrategy.cpp |
| @@ -0,0 +1,135 @@ |
| +// Copyright 2015 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "config.h" |
| +#include "core/editing/GranularityStrategy.h" |
| + |
| +#include "core/editing/htmlediting.h" |
| + |
| +namespace blink { |
| + |
| +///////////////////////////////////////////////////////////////////// |
|
yosin_UTC9
2015/04/23 03:38:47
nit: We don't need have HR like banner comments.
mfomitchev
2015/04/23 15:08:11
Done.
|
| +// GranularityStrategy implementation |
| + |
| +GranularityStrategy::GranularityStrategy() { } |
| + |
| +GranularityStrategy::~GranularityStrategy() { } |
| + |
| +///////////////////////////////////////////////////////////////////// |
| +// CharacterGranularityStrategy implementation |
| + |
| +CharacterGranularityStrategy::CharacterGranularityStrategy() { } |
| + |
| +CharacterGranularityStrategy::~CharacterGranularityStrategy() { } |
| + |
| +SelectionStrategy CharacterGranularityStrategy::GetType() const |
| +{ |
| + return SelectionStrategy::Character; |
| +} |
| + |
| +void CharacterGranularityStrategy::Clear() { }; |
| + |
| +VisibleSelection CharacterGranularityStrategy::updateExtent(const VisiblePosition& extentPosition, const VisibleSelection& selection) |
| +{ |
| + return VisibleSelection(selection.visibleBase(), extentPosition); |
| +} |
| + |
| +///////////////////////////////////////////////////////////////////// |
| +// DirectionGranularityStrategy implementation |
| + |
| +DirectionGranularityStrategy::DirectionGranularityStrategy() |
| + : m_granularity(CharacterGranularity) |
| + , m_lastMoveShrunkSelection(false) { } |
| + |
| +DirectionGranularityStrategy::~DirectionGranularityStrategy() { } |
| + |
| +SelectionStrategy DirectionGranularityStrategy::GetType() const |
| +{ |
| + return SelectionStrategy::Direction; |
| +} |
| + |
| +void DirectionGranularityStrategy::Clear() |
| +{ |
| + m_granularity = CharacterGranularity; |
| + m_lastMoveShrunkSelection = false; |
| +} |
| + |
| +VisiblePosition DirectionGranularityStrategy::nextWordBound( |
| + const VisiblePosition& pos, |
| + SearchDirection direction, |
| + BoundAdjust wordBoundAdjust) |
| +{ |
| + bool nextBoundIfOnBound = wordBoundAdjust == BoundAdjust::NextBoundIfOnBound; |
| + if (direction == SearchDirection::SearchForward) { |
| + EWordSide wordSide = nextBoundIfOnBound ? RightWordIfOnBoundary : LeftWordIfOnBoundary; |
| + return endOfWord(pos, wordSide); |
| + } |
| + EWordSide wordSide = nextBoundIfOnBound ? LeftWordIfOnBoundary : RightWordIfOnBoundary; |
| + return startOfWord(pos, wordSide); |
| +} |
| + |
| +VisibleSelection DirectionGranularityStrategy::updateExtent(const VisiblePosition& extentPosition, const VisibleSelection& selection) |
| +{ |
| + if (extentPosition == selection.visibleExtent()) |
| + return selection; |
| + |
| + const VisiblePosition base = selection.visibleBase(); |
| + const VisiblePosition oldExtentWithGranularity = selection.isBaseFirst() ? selection.visibleEnd() : selection.visibleStart(); |
| + |
| + int extentBaseOrder = comparePositions(extentPosition, base); |
| + int oldExtentBaseOrder = comparePositions(oldExtentWithGranularity, base); |
| + |
| + bool extentBaseOrderSwitched = (extentBaseOrder > 0 && oldExtentBaseOrder < 0) |
| + || (extentBaseOrder < 0 && oldExtentBaseOrder > 0); |
| + |
| + // Determine the boundary of the 'current word', i.e. the boundary extending beyond which |
|
yosin_UTC9
2015/04/23 03:38:47
OPTIONAL: It is nice to format comment less than 8
mfomitchev
2015/04/23 15:08:11
Done.
|
| + // should change the granularity to WordGranularity. |
| + // If the last move has shrunk the selection and is now exactly on the word boundary - |
| + // we need to take the next bound as the bound of the "current word". |
| + VisiblePosition currentWordBoundary = nextWordBound( |
| + oldExtentWithGranularity, |
| + oldExtentBaseOrder > 0 ? SearchDirection::SearchForward : SearchDirection::SearchBackwards, |
| + m_lastMoveShrunkSelection ? BoundAdjust::NextBoundIfOnBound : BoundAdjust::CurrentPosIfOnBound); |
| + |
| + bool thisMoveShrunkSelection = (extentBaseOrder > 0 && comparePositions(extentPosition, selection.visibleExtent()) < 0) |
| + || (extentBaseOrder < 0 && comparePositions(extentPosition, selection.visibleExtent()) > 0); |
| + // If the extent-base order was switched, then the selection is now expanding in a different |
| + // direction than before. Therefore we need to calculate the boundary of the 'current word' |
| + // in this new direction in order to be able to tell if the selection expanded beyond it. |
| + if (extentBaseOrderSwitched) { |
| + currentWordBoundary = nextWordBound( |
| + base, |
| + extentBaseOrder > 0 ? SearchDirection::SearchForward : SearchDirection::SearchBackwards, |
| + BoundAdjust::NextBoundIfOnBound); |
| + m_granularity = CharacterGranularity; |
| + // When the base/extent order switches it doesn't count as shrinking selection. |
| + thisMoveShrunkSelection = false; |
| + } |
| + |
| + bool expandedBeyondWordBoundary; |
| + if (extentBaseOrder > 0) |
| + expandedBeyondWordBoundary = comparePositions(extentPosition, currentWordBoundary) > 0; |
| + else |
| + expandedBeyondWordBoundary = comparePositions(extentPosition, currentWordBoundary) < 0; |
| + if (expandedBeyondWordBoundary) { |
| + m_granularity = WordGranularity; |
| + } else if (thisMoveShrunkSelection) { |
| + m_granularity = CharacterGranularity; |
| + m_lastMoveShrunkSelection = true; |
| + } |
| + |
| + m_lastMoveShrunkSelection = thisMoveShrunkSelection; |
| + VisibleSelection newSelection = selection; |
| + newSelection.setExtent(extentPosition); |
| + if (m_granularity == WordGranularity) { |
| + if (extentBaseOrder > 0) |
| + newSelection.setEndRespectingGranularity(m_granularity, LeftWordIfOnBoundary); |
| + else |
| + newSelection.setStartRespectingGranularity(m_granularity, RightWordIfOnBoundary); |
| + } |
| + |
| + return newSelection; |
| +} |
| + |
| +} // namespace blink |