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

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

Issue 988023005: Implementing directional selection strategy in Blink. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Putting GranularityStrategy into separate files. Created 5 years, 8 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
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

Powered by Google App Engine
This is Rietveld 408576698