summaryrefslogtreecommitdiffstats
path: root/WebCore/dom/Position.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/dom/Position.cpp')
-rw-r--r--WebCore/dom/Position.cpp47
1 files changed, 33 insertions, 14 deletions
diff --git a/WebCore/dom/Position.cpp b/WebCore/dom/Position.cpp
index fa994e3..fdcd7e5 100644
--- a/WebCore/dom/Position.cpp
+++ b/WebCore/dom/Position.cpp
@@ -986,27 +986,46 @@ static InlineTextBox* searchAheadForBetterMatch(RenderObject* renderer)
return 0;
}
+static Position downstreamIgnoringEditingBoundaries(Position position)
+{
+ Position lastPosition;
+ while (position != lastPosition) {
+ lastPosition = position;
+ position = position.downstream(Position::CanCrossEditingBoundary);
+ }
+ return position;
+}
+
+static Position upstreamIgnoringEditingBoundaries(Position position)
+{
+ Position lastPosition;
+ while (position != lastPosition) {
+ lastPosition = position;
+ position = position.upstream(Position::CanCrossEditingBoundary);
+ }
+ return position;
+}
+
void Position::getInlineBoxAndOffset(EAffinity affinity, TextDirection primaryDirection, InlineBox*& inlineBox, int& caretOffset) const
{
caretOffset = m_offset;
RenderObject* renderer = node()->renderer();
-
+
if (!renderer->isText()) {
- if (!renderer->isRenderButton() && renderer->isBlockFlow() && hasRenderedNonAnonymousDescendantsWithHeight(renderer)) {
- bool lastPosition = caretOffset == lastOffsetInNode(node());
- Node* startNode = lastPosition ? node()->childNode(caretOffset - 1) : node()->childNode(caretOffset);
- while (startNode && (!startNode->renderer() || (startNode->isTextNode() && toRenderText(startNode->renderer())->isAllCollapsibleWhitespace())))
- startNode = (lastPosition)? startNode->previousSibling(): startNode->nextSibling();
- if (startNode) {
- Position pos(startNode, 0);
- pos = pos.downstream(CanCrossEditingBoundary);
- pos.getInlineBoxAndOffset(UPSTREAM, primaryDirection, inlineBox, caretOffset);
- if (lastPosition && inlineBox)
- caretOffset = inlineBox->caretMaxOffset();
+ inlineBox = 0;
+ if (canHaveChildrenForEditing(node()) && renderer->isBlockFlow() && hasRenderedNonAnonymousDescendantsWithHeight(renderer)) {
+ // Try a visually equivalent position with possibly opposite editability. This helps in case |this| is in
+ // an editable block but surrounded by non-editable positions. It acts to negate the logic at the beginning
+ // of RenderObject::createVisiblePosition().
+ Position equivalent = downstreamIgnoringEditingBoundaries(*this);
+ if (equivalent == *this)
+ equivalent = upstreamIgnoringEditingBoundaries(*this);
+ if (equivalent == *this)
return;
- }
+
+ equivalent.getInlineBoxAndOffset(UPSTREAM, primaryDirection, inlineBox, caretOffset);
+ return;
}
- inlineBox = 0;
if (renderer->isBox()) {
inlineBox = toRenderBox(renderer)->inlineBoxWrapper();
if (!inlineBox || (caretOffset > inlineBox->caretMinOffset() && caretOffset < inlineBox->caretMaxOffset()))