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

Unified Diff: third_party/WebKit/Source/core/editing/PositionIterator.cpp

Issue 2720593005: Make PositionIterator to skip contents of INPUT/SELECT/TEXTAREA (Closed)
Patch Set: 2017-03-02T19:03:48 Add FrameSelectionTest.SelectAllWithInputElement Created 3 years, 10 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: third_party/WebKit/Source/core/editing/PositionIterator.cpp
diff --git a/third_party/WebKit/Source/core/editing/PositionIterator.cpp b/third_party/WebKit/Source/core/editing/PositionIterator.cpp
index 2e875770f473ac2bafb167e19bdfbb81f1de3e8f..e26609b91f04e2d0c5cd788d000da7e7154dd0a0 100644
--- a/third_party/WebKit/Source/core/editing/PositionIterator.cpp
+++ b/third_party/WebKit/Source/core/editing/PositionIterator.cpp
@@ -25,8 +25,29 @@
#include "core/editing/PositionIterator.h"
+#include "core/editing/EditingUtilities.h"
+
namespace blink {
+namespace {
+
+// TODO(editing-dev): We should replace usages of |hasChildren()| in
+// |PositionIterator| to |shouldTraverseChildren()|.
+template <typename Strategy>
+bool shouldTraverseChildren(const Node& node) {
+ return Strategy::hasChildren(node) && !isUserSelectContain(node);
+}
+
+// TODO(editing-dev): We should replace usages of |parent()| in
+// |PositionIterator| to |selectableParentOf()|.
+template <typename Strategy>
+ContainerNode* selectableParentOf(const Node& node) {
+ ContainerNode* const parent = Strategy::parent(node);
+ return parent && !isUserSelectContain(*parent) ? parent : nullptr;
+}
+
+} // namespace
+
static const int kInvalidOffset = -1;
template <typename Strategy>
@@ -39,8 +60,8 @@ PositionIteratorAlgorithm<Strategy>::PositionIteratorAlgorithm(
m_offsetInAnchor(m_nodeAfterPositionInAnchor ? 0 : offsetInAnchor),
m_depthToAnchorNode(0),
m_domTreeVersion(anchorNode->document().domTreeVersion()) {
- for (Node* node = Strategy::parent(*anchorNode); node;
- node = Strategy::parent(*node)) {
+ for (Node* node = selectableParentOf<Strategy>(*anchorNode); node;
+ node = selectableParentOf<Strategy>(*node)) {
// Each m_offsetsInAnchorNode[offset] should be an index of node in
// parent, but delay to calculate the index until it is needed for
// performance.
@@ -108,7 +129,7 @@ PositionIteratorAlgorithm<Strategy>::computePosition() const {
return PositionTemplate<Strategy>(
m_anchorNode, m_offsetsInAnchorNode[m_depthToAnchorNode]);
}
- if (Strategy::hasChildren(*m_anchorNode))
+ if (shouldTraverseChildren<Strategy>(*m_anchorNode))
// For example, position is the end of B.
return PositionTemplate<Strategy>::lastPositionInOrAfterNode(m_anchorNode);
if (m_anchorNode->isTextNode())
@@ -147,7 +168,10 @@ void PositionIteratorAlgorithm<Strategy>::increment() {
// Let |anchor| is A and |child| is B,
// then next |anchor| is B and |child| is E.
m_anchorNode = m_nodeAfterPositionInAnchor;
- m_nodeAfterPositionInAnchor = Strategy::firstChild(*m_anchorNode);
+ m_nodeAfterPositionInAnchor =
+ shouldTraverseChildren<Strategy>(*m_anchorNode)
+ ? Strategy::firstChild(*m_anchorNode)
+ : nullptr;
m_offsetInAnchor = 0;
// Increment depth intializing with 0.
++m_depthToAnchorNode;
@@ -158,7 +182,8 @@ void PositionIteratorAlgorithm<Strategy>::increment() {
return;
}
- if (m_anchorNode->layoutObject() && !Strategy::hasChildren(*m_anchorNode) &&
+ if (m_anchorNode->layoutObject() &&
+ !shouldTraverseChildren<Strategy>(*m_anchorNode) &&
m_offsetInAnchor < Strategy::lastOffsetForEditing(m_anchorNode)) {
// Case #2. This is the next of Case #1 or #2 itself.
// Position is (|anchor|, |m_offsetInAchor|).
@@ -174,7 +199,7 @@ void PositionIteratorAlgorithm<Strategy>::increment() {
// 3-b. If |anchor| doesn't have next sibling (let F),
// next |anchor| is B and |child| is null. (next is Case #3.)
m_nodeAfterPositionInAnchor = m_anchorNode;
- m_anchorNode = Strategy::parent(*m_nodeAfterPositionInAnchor);
+ m_anchorNode = selectableParentOf<Strategy>(*m_nodeAfterPositionInAnchor);
if (!m_anchorNode)
return;
DCHECK_GT(m_depthToAnchorNode, 0u);
@@ -219,7 +244,7 @@ void PositionIteratorAlgorithm<Strategy>::decrement() {
// Let |anchor| is B and |child| is F,
// next |anchor| is E and |child| is null.
m_nodeAfterPositionInAnchor = nullptr;
- m_offsetInAnchor = Strategy::hasChildren(*m_anchorNode)
+ m_offsetInAnchor = shouldTraverseChildren<Strategy>(*m_anchorNode)
? 0
: Strategy::lastOffsetForEditing(m_anchorNode);
// Decrement offset of |child| or initialize if it have never been
@@ -244,7 +269,7 @@ void PositionIteratorAlgorithm<Strategy>::decrement() {
// next |anchor| is A and |child| is B.
m_nodeAfterPositionInAnchor =
Strategy::parent(*m_nodeAfterPositionInAnchor);
- m_anchorNode = Strategy::parent(*m_nodeAfterPositionInAnchor);
+ m_anchorNode = selectableParentOf<Strategy>(*m_nodeAfterPositionInAnchor);
if (!m_anchorNode)
return;
m_offsetInAnchor = 0;
@@ -258,11 +283,11 @@ void PositionIteratorAlgorithm<Strategy>::decrement() {
return;
}
- if (Strategy::hasChildren(*m_anchorNode)) {
+ if (shouldTraverseChildren<Strategy>(*m_anchorNode)) {
// Case #2. This is a reverse of increment()::Case3-b.
// Let |anchor| is B, next |anchor| is F.
m_anchorNode = Strategy::lastChild(*m_anchorNode);
- m_offsetInAnchor = Strategy::hasChildren(*m_anchorNode)
+ m_offsetInAnchor = shouldTraverseChildren<Strategy>(*m_anchorNode)
? 0
: Strategy::lastOffsetForEditing(m_anchorNode);
// Decrement depth initializing with -1 because
@@ -274,7 +299,6 @@ void PositionIteratorAlgorithm<Strategy>::decrement() {
++m_depthToAnchorNode;
return;
}
-
if (m_offsetInAnchor && m_anchorNode->layoutObject()) {
// Case #3-a. This is a reverse of increment()::Case#2.
// In this case |anchor| is a leaf(E,F,C,G or H) and
@@ -290,7 +314,7 @@ void PositionIteratorAlgorithm<Strategy>::decrement() {
// Let |anchor| is E,
// next |anchor| is B and |child| is E.
m_nodeAfterPositionInAnchor = m_anchorNode;
- m_anchorNode = Strategy::parent(*m_anchorNode);
+ m_anchorNode = selectableParentOf<Strategy>(*m_anchorNode);
if (!m_anchorNode)
return;
DCHECK_GT(m_depthToAnchorNode, 0u);

Powered by Google App Engine
This is Rietveld 408576698