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

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

Issue 1123563003: Improving direction-based selection strategy. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: 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
« no previous file with comments | « Source/core/editing/GranularityStrategy.h ('k') | Source/core/editing/VisibleSelection.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/core/editing/GranularityStrategy.cpp
diff --git a/Source/core/editing/GranularityStrategy.cpp b/Source/core/editing/GranularityStrategy.cpp
index 5a5fd9ee30330abf12efdd949c68fff152dc0636..a2ef3d7d08dc1b5f8e1db2264921090cb0176026 100644
--- a/Source/core/editing/GranularityStrategy.cpp
+++ b/Source/core/editing/GranularityStrategy.cpp
@@ -5,9 +5,28 @@
#include "config.h"
#include "core/editing/GranularityStrategy.h"
+#include "core/editing/FrameSelection.h"
#include "core/editing/htmlediting.h"
+#include "core/layout/HitTestRequest.h"
+#include "core/layout/HitTestResult.h"
+#include "core/layout/LayoutView.h"
+#include "core/paint/DeprecatedPaintLayer.h"
+
namespace blink {
+namespace {
+
+VisiblePosition visiblePositionForFramePoint(const IntPoint& framePoint, LocalFrame* frame)
+{
+ HitTestRequest request = HitTestRequest::Move | HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::IgnoreClipping;
+ HitTestResult result(request, framePoint);
+ frame->document()->layoutView()->layer()->hitTest(result);
+
+ if (Node* node = result.innerNode())
+ return frame->selection().selection().visiblePositionRespectingEditingBoundary(result.localPoint(), node);
+ return VisiblePosition();
+}
+}
GranularityStrategy::GranularityStrategy() { }
@@ -24,14 +43,19 @@ SelectionStrategy CharacterGranularityStrategy::GetType() const
void CharacterGranularityStrategy::Clear() { };
-VisibleSelection CharacterGranularityStrategy::updateExtent(const VisiblePosition& extentPosition, const VisibleSelection& selection)
+VisibleSelection CharacterGranularityStrategy::updateExtent(const IntPoint& framePoint, LocalFrame* frame)
{
+ const VisiblePosition& extentPosition = visiblePositionForFramePoint(framePoint, frame);
+ const VisibleSelection& selection = frame->selection().selection();
+ if (selection.visibleBase() == extentPosition)
+ return selection;
return VisibleSelection(selection.visibleBase(), extentPosition);
}
DirectionGranularityStrategy::DirectionGranularityStrategy()
: m_granularity(CharacterGranularity)
- , m_lastMoveShrunkSelection(false) { }
+ , m_lastMoveShrunkSelection(false)
+ , m_offset(0) { }
DirectionGranularityStrategy::~DirectionGranularityStrategy() { }
@@ -44,6 +68,7 @@ void DirectionGranularityStrategy::Clear()
{
m_granularity = CharacterGranularity;
m_lastMoveShrunkSelection = false;
+ m_offset = 0;
}
VisiblePosition DirectionGranularityStrategy::nextWordBound(
@@ -60,9 +85,24 @@ VisiblePosition DirectionGranularityStrategy::nextWordBound(
return startOfWord(pos, wordSide);
}
-VisibleSelection DirectionGranularityStrategy::updateExtent(const VisiblePosition& extentPosition, const VisibleSelection& selection)
+VisibleSelection DirectionGranularityStrategy::updateExtent(const IntPoint& extentPoint, LocalFrame* frame)
{
- if (extentPosition == selection.visibleExtent())
+ // Apply the offset if needed
+ IntPoint offsetExtentPoint = extentPoint;
+ if (m_offset != 0) {
+ int dx = extentPoint.x() - m_extentPoint.x();
+ if (m_offset > 0 && dx > 0)
+ m_offset = std::max(0, m_offset - dx);
+ else if (m_offset < 0 && dx < 0)
+ m_offset = std::min(0, m_offset - dx);
+ offsetExtentPoint.move(m_offset, 0);
+ }
+ m_extentPoint = extentPoint;
+
+ VisiblePosition extentPosition = visiblePositionForFramePoint(offsetExtentPoint, frame);
+ const VisibleSelection& selection = frame->selection().selection();
+
+ if (selection.visibleBase() == extentPosition || extentPosition == selection.visibleExtent())
return selection;
const VisiblePosition base = selection.visibleBase();
@@ -108,18 +148,51 @@ VisibleSelection DirectionGranularityStrategy::updateExtent(const VisiblePositio
if (expandedBeyondWordBoundary) {
m_granularity = WordGranularity;
} else if (thisMoveShrunkSelection) {
+ // If the offset is 0, we may need to update it and apply the offset to the extent.
+ if (m_offset == 0) {
+ if (extentBaseOrder > 0) {
+ if (selection.end() != selection.extent())
+ m_offset = selection.visibleEnd().absoluteCaretBounds().x() - selection.visibleExtent().absoluteCaretBounds().x();
+ } else {
+ if (selection.start() != selection.extent())
+ m_offset = selection.visibleStart().absoluteCaretBounds().x() - selection.visibleExtent().absoluteCaretBounds().x();
+ }
+ if (m_offset != 0) {
+ offsetExtentPoint.move(m_offset, 0);
+ extentPosition = visiblePositionForFramePoint(offsetExtentPoint, frame);
+ }
+ }
m_granularity = CharacterGranularity;
m_lastMoveShrunkSelection = true;
}
m_lastMoveShrunkSelection = thisMoveShrunkSelection;
VisibleSelection newSelection = selection;
- newSelection.setExtent(extentPosition);
- if (m_granularity == WordGranularity) {
- if (extentBaseOrder > 0)
+
+ if (m_granularity == CharacterGranularity) {
+ newSelection.setExtent(extentPosition);
+ } else {
+ // Need to adjust extent by one position for the purposes of setting the
+ // selection if the length of the current word is greater than 3.
+ // This is so that the selection only expands to the end of the word when
+ // the extent moves beyond the first character for words that are more
+ // than 3 characters long.
+ bool adjustExtent = false;
+ Position boundBeforeExtent = nextWordBound(extentPosition, SearchDirection::SearchBackwards, BoundAdjust::CurrentPosIfOnBound).deepEquivalent();
+ if (boundBeforeExtent != extentPosition.deepEquivalent()) {
+ Position boundAfterExtent = nextWordBound(extentPosition, SearchDirection::SearchForward, BoundAdjust::CurrentPosIfOnBound).deepEquivalent();
+ int wordLength = boundAfterExtent.offsetInContainerNode() - boundBeforeExtent.offsetInContainerNode();
+ adjustExtent = wordLength > 3;
+ }
+
+ if (extentBaseOrder > 0) {
+ newSelection.setExtent(adjustExtent ? extentPosition.previous() : extentPosition);
newSelection.setEndRespectingGranularity(m_granularity, LeftWordIfOnBoundary);
- else
+ } else {
+ newSelection.setExtent(adjustExtent ? extentPosition.next() : extentPosition);
newSelection.setStartRespectingGranularity(m_granularity, RightWordIfOnBoundary);
+ }
+ newSelection.setWithoutValidation(newSelection.base(), extentPosition.deepEquivalent(), newSelection.start(), newSelection.end());
mfomitchev 2015/05/01 23:31:51 Note we actually only need to set the extent witho
}
return newSelection;
« no previous file with comments | « Source/core/editing/GranularityStrategy.h ('k') | Source/core/editing/VisibleSelection.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698