return (b1 && b2 && b1->root() != b2->root());
}
-bool visiblePositionsInDifferentBlocks(const VisiblePosition &pos1, const VisiblePosition &pos2)
+enum EBlockRelationship {
+ NoBlockRelationship,
+ SameBlockRelationship,
+ PeerBlockRelationship,
+ AncestorBlockRelationship,
+ DescendantBlockRelationship,
+ OtherBlockRelationship
+};
+
+static EBlockRelationship blockRelationship(const VisiblePosition &pos1, const VisiblePosition &pos2)
{
if (pos1.isNull() || pos2.isNull())
- return false;
+ return NoBlockRelationship;
if (pos1 == pos2)
- return false;
+ return SameBlockRelationship;
Position p1 = pos1.deepEquivalent();
Position p2 = pos2.deepEquivalent();
NodeImpl *b1 = p1.node()->enclosingBlockFlowElement();
NodeImpl *b2 = p2.node()->enclosingBlockFlowElement();
- return (b1 != b2);
+ if (!b1 || !b2)
+ return NoBlockRelationship;
+ if (b1 == b2)
+ return SameBlockRelationship;
+ if (b1->parentNode() == b2->parentNode())
+ return PeerBlockRelationship;
+ if (b2->isAncestor(b1))
+ return AncestorBlockRelationship;
+ if (b1->isAncestor(b2))
+ return DescendantBlockRelationship;
+ return OtherBlockRelationship;
+}
+
+bool visiblePositionsInDifferentBlocks(const VisiblePosition &pos1, const VisiblePosition &pos2)
+{
+ switch (blockRelationship(pos1, pos2)) {
+ case NoBlockRelationship:
+ case SameBlockRelationship:
+ return false;
+ case PeerBlockRelationship:
+ case AncestorBlockRelationship:
+ case DescendantBlockRelationship:
+ case OtherBlockRelationship:
+ return true;
+ }
+ ASSERT_NOT_REACHED();
+ return false;
}
bool isFirstVisiblePositionOnLine(const VisiblePosition &pos)
return previous.isNull() || visiblePositionsOnDifferentLines(pos, previous);
}
+bool isFirstVisiblePositionInBlock(const VisiblePosition &pos)
+{
+ if (pos.isNull())
+ return false;
+
+ VisiblePosition previous = pos.previous();
+ if (previous.isNull())
+ return true;
+
+ switch (blockRelationship(pos, previous)) {
+ case NoBlockRelationship:
+ case SameBlockRelationship:
+ case AncestorBlockRelationship:
+ return false;
+ case PeerBlockRelationship:
+ case DescendantBlockRelationship:
+ case OtherBlockRelationship:
+ return true;
+ }
+ ASSERT_NOT_REACHED();
+ return false;
+}
+
+bool isFirstVisiblePositionInNode(const VisiblePosition &pos, const NodeImpl *node)
+{
+ if (pos.isNull())
+ return false;
+
+ VisiblePosition previous = pos.previous();
+ return previous.isNull() || !previous.deepEquivalent().node()->isAncestor(node);
+}
+
bool isLastVisiblePositionOnLine(const VisiblePosition &pos)
{
if (pos.isNull())
return false;
VisiblePosition next = pos.next();
- return next.isNull() || visiblePositionsInDifferentBlocks(pos, next);
+ if (next.isNull())
+ return true;
+
+ switch (blockRelationship(pos, next)) {
+ case NoBlockRelationship:
+ case SameBlockRelationship:
+ case DescendantBlockRelationship:
+ return false;
+ case PeerBlockRelationship:
+ case AncestorBlockRelationship:
+ case OtherBlockRelationship:
+ return true;
+ }
+ ASSERT_NOT_REACHED();
+ return false;
}
bool isLastVisiblePositionInNode(const VisiblePosition &pos, const NodeImpl *node)