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..a2ac47b34639a7d0c1e9fef09524695345aaf161 |
--- /dev/null |
+++ b/Source/core/editing/GranularityStrategy.cpp |
@@ -0,0 +1,126 @@ |
+/* |
yosin_UTC9
2015/04/21 01:59:51
nit: Let's use the short version of licence commen
mfomitchev
2015/04/21 18:44:25
Done.
|
+ * Copyright 2015, Google Inc. All rights reserved. |
+ * |
+ * Redistribution and use in source and binary forms, with or without |
+ * modification, are permitted provided that the following conditions are |
+ * met: |
+ * |
+ * * Redistributions of source code must retain the above copyright |
+ * notice, this list of conditions and the following disclaimer. |
+ * * Redistributions in binary form must reproduce the above |
+ * copyright notice, this list of conditions and the following disclaimer |
+ * in the documentation and/or other materials provided with the |
+ * distribution. |
+ * * Neither the name of Google Inc. nor the names of its |
+ * contributors may be used to endorse or promote products derived from |
+ * this software without specific prior written permission. |
+ * |
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
+ */ |
+ |
+#include "config.h" |
+#include "core/editing/GranularityStrategy.h" |
+ |
+#include "core/editing/htmlediting.h" |
+ |
+namespace blink { |
+ |
+VisibleSelection CharacterGranularityStrategy::updateExtent(const VisiblePosition& extentPosition, const VisibleSelection& selection) |
+{ |
+ return VisibleSelection(selection.visibleBase(), extentPosition); |
+} |
+ |
+DirectionGranularityStrategy::DirectionGranularityStrategy() |
+ : m_granularity(CharacterGranularity) |
+ , m_lastMoveShrunkSelection(false) { } |
+ |
+void DirectionGranularityStrategy::Clear() |
+{ |
+ m_granularity = CharacterGranularity; |
+ m_lastMoveShrunkSelection = false; |
+} |
+ |
+VisiblePosition DirectionGranularityStrategy::nextWordBound( |
+ const VisiblePosition& pos, |
+ ESearchDirection direction, |
+ EBoundAdjust wordBoundAdjust) |
+{ |
+ if (direction == ESearchDirection::SearchForward) |
yosin_UTC9
2015/04/21 01:59:51
Q: How about using if-statement rather than ternar
mfomitchev
2015/04/21 18:44:25
I moved the ternary operator out and added a bool
|
+ return endOfWord(pos, wordBoundAdjust == EBoundAdjust::CurrentPosIfOnBound ? LeftWordIfOnBoundary : RightWordIfOnBoundary); |
+ return startOfWord(pos, wordBoundAdjust == EBoundAdjust::CurrentPosIfOnBound ? RightWordIfOnBoundary : LeftWordIfOnBoundary); |
+} |
+ |
+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 |
+ // 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 ? ESearchDirection::SearchForward : ESearchDirection::SearchBackwards, |
+ m_lastMoveShrunkSelection ? EBoundAdjust::NextBoundIfOnBound : EBoundAdjust::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 ? ESearchDirection::SearchForward : ESearchDirection::SearchBackwards, |
+ EBoundAdjust::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 |