+2005-02-14 David Harrison <harrison@apple.com>
+
+ Reviewed by Darin.
+
+ <rdar://problem/4004305> REGRESSION (Mail): Command-right-arrow on wrapped text goes to end of previous line
+
+ Fixed nextLinePosition to calculate affinity rather than take it as a parameter. Propagated the parameter change out to related methods.
+
+ * khtml/editing/htmlediting.cpp:
+ (khtml::DeleteSelectionCommand::initializePositionData):
+ (khtml::InsertLineBreakCommand::doApply):
+ (khtml::InsertParagraphSeparatorCommand::doApply):
+ (khtml::InsertTextCommand::input):
+ (khtml::ReplaceSelectionCommand::doApply):
+ (khtml::ReplaceSelectionCommand::applyStyleToInsertedNodes):
+ * khtml/editing/selection.cpp:
+ (khtml::Selection::modifyExtendingRightForward):
+ (khtml::Selection::modifyMovingRightForward):
+ (khtml::Selection::modifyExtendingLeftBackward):
+ (khtml::Selection::modifyMovingLeftBackward):
+ (khtml::Selection::modify):
+ (khtml::Selection::validate):
+ * khtml/editing/visible_position.cpp:
+ (khtml::visiblePositionsOnDifferentLines):
+ * khtml/editing/visible_units.cpp:
+ (khtml::rootBoxForLine):
+ (khtml::startOfLine):
+ (khtml::endOfLine):
+ (khtml::inSameLine):
+ (khtml::isStartOfLine):
+ (khtml::isEndOfLine):
+ (khtml::previousLinePosition):
+ (khtml::nextLinePosition):
+ (khtml::previousSentencePosition):
+ (khtml::nextSentencePosition):
+ (khtml::previousParagraphPosition):
+ (khtml::nextParagraphPosition):
+ * khtml/editing/visible_units.h:
+ * khtml/khtml_events.cpp:
+ (khtml::MouseEvent::offset):
+ * khtml/khtml_part.cpp:
+ (KHTMLPart::isPointInsideSelection):
+ (KHTMLPart::selectClosestWordFromMouseEvent):
+ (KHTMLPart::handleMousePressEventTripleClick):
+ (KHTMLPart::handleMousePressEventSingleClick):
+ (KHTMLPart::handleMouseMoveEventSelection):
+ (KHTMLPart::khtmlMouseReleaseEvent):
+ * khtml/rendering/render_block.cpp:
+ (khtml::RenderBlock::positionForCoordinates):
+ * khtml/rendering/render_block.h:
+ * khtml/rendering/render_br.cpp:
+ (RenderBR::positionForCoordinates):
+ * khtml/rendering/render_br.h:
+ * khtml/rendering/render_container.cpp:
+ (RenderContainer::positionForCoordinates):
+ * khtml/rendering/render_container.h:
+ * khtml/rendering/render_inline.cpp:
+ (RenderInline::positionForCoordinates):
+ * khtml/rendering/render_inline.h:
+ * khtml/rendering/render_object.cpp:
+ (RenderObject::caretRect):
+ (RenderObject::positionForCoordinates):
+ * khtml/rendering/render_object.h:
+ * khtml/rendering/render_replaced.cpp:
+ (RenderReplaced::positionForCoordinates):
+ * khtml/rendering/render_replaced.h:
+ * khtml/rendering/render_text.cpp:
+ (RenderText::positionForCoordinates):
+ * khtml/rendering/render_text.h:
+ * khtml/xml/dom_position.cpp:
+ (DOM::Position::previousCharacterPosition):
+ (DOM::Position::nextCharacterPosition):
+ (DOM::Position::leadingWhitespacePosition):
+ (DOM::Position::trailingWhitespacePosition):
+ * khtml/xml/dom_position.h:
+ * kwq/KWQAccObject.mm:
+ (-[KWQAccObject value]):
+ (-[KWQAccObject accessibilityAttributeValue:]):
+ (-[KWQAccObject doAXLineForTextMarker:]):
+ (-[KWQAccObject doAXTextMarkerRangeForLine:]):
+ (-[KWQAccObject doAXTextMarkerForPosition:]):
+ (-[KWQAccObject doAXLeftLineTextMarkerRangeForTextMarker:]):
+ (-[KWQAccObject doAXRightLineTextMarkerRangeForTextMarker:]):
+ (-[KWQAccObject doAXNextLineEndTextMarkerForTextMarker:]):
+ (-[KWQAccObject doAXPreviousLineStartTextMarkerForTextMarker:]):
+ * kwq/KWQKHTMLPart.mm:
+ * kwq/WebCoreBridge.mm:
+ (-[WebCoreBridge _visiblePositionForPoint:]):
+
05-02-07 Maciej Stachowiak <mjs@apple.com>
Reviewed by Ken and John.
pos = nextWordPosition(pos);
break;
case PARAGRAPH:
- pos = nextParagraphPosition(pos, m_affinity, xPosForVerticalArrowNavigation(EXTENT));
+ pos = nextParagraphPosition(pos, xPosForVerticalArrowNavigation(EXTENT));
break;
case LINE:
- pos = nextLinePosition(pos, m_affinity, xPosForVerticalArrowNavigation(EXTENT));
+ pos = nextLinePosition(pos, xPosForVerticalArrowNavigation(EXTENT));
break;
case LINE_BOUNDARY:
- pos = endOfLine(VisiblePosition(m_end, m_affinity), UPSTREAM);
+ pos = endOfLine(VisiblePosition(m_end, m_affinity));
break;
case PARAGRAPH_BOUNDARY:
pos = endOfParagraph(VisiblePosition(m_end, m_affinity));
pos = nextWordPosition(VisiblePosition(m_extent, m_affinity));
break;
case PARAGRAPH:
- pos = nextParagraphPosition(VisiblePosition(m_end, m_affinity), m_affinity, xPosForVerticalArrowNavigation(END, isRange()));
+ pos = nextParagraphPosition(VisiblePosition(m_end, m_affinity), xPosForVerticalArrowNavigation(END, isRange()));
break;
case LINE: {
- // This somewhat complicated code is needed to handle the case where there is a
- // whole line selected (like when the user clicks at the start of a line and hits shift+down-arrow),
- // and then hits an (unshifted) down arrow. Since the whole-line selection considers its
- // ending point to be the start of the next line, it may be necessary to juggle the
- // position to use as the VisiblePosition to pass to nextLinePosition(). If this juggling
- // is not done, you can wind up skipping a line. See these two bugs for more information:
- // <rdar://problem/3875618> REGRESSION (Mail): Hitting down arrow with full line selected skips line (br case)
- // <rdar://problem/3875641> REGRESSION (Mail): Hitting down arrow with full line selected skips line (div case)
- if (isCaret()) {
- pos = VisiblePosition(m_end, m_affinity);
- } else if (isRange()) {
- Position p(m_end.upstream());
- if (p.node()->id() == ID_BR)
- pos = VisiblePosition(Position(p.node(), 0), UPSTREAM);
- else
- pos = VisiblePosition(p, UPSTREAM);
- }
- pos = nextLinePosition(pos, m_affinity, xPosForVerticalArrowNavigation(END, isRange()));
+ // down-arrowing from a range selection that ends at the start of a line needs
+ // to leave the selection at that line start (no need to call nextLinePosition!)
+ pos = VisiblePosition(m_end, m_affinity);
+ if (!isRange() || !isStartOfLine(pos))
+ pos = nextLinePosition(pos, xPosForVerticalArrowNavigation(END, isRange()));
break;
}
case LINE_BOUNDARY:
- pos = endOfLine(VisiblePosition(m_end, m_affinity), UPSTREAM);
+ pos = endOfLine(VisiblePosition(m_end, m_affinity));
break;
case PARAGRAPH_BOUNDARY:
pos = endOfParagraph(VisiblePosition(m_end, m_affinity));
pos = previousWordPosition(pos);
break;
case PARAGRAPH:
- pos = previousParagraphPosition(pos, m_affinity, xPosForVerticalArrowNavigation(EXTENT));
+ pos = previousParagraphPosition(pos, xPosForVerticalArrowNavigation(EXTENT));
break;
case LINE:
- pos = previousLinePosition(pos, m_affinity, xPosForVerticalArrowNavigation(EXTENT));
+ pos = previousLinePosition(pos, xPosForVerticalArrowNavigation(EXTENT));
break;
case LINE_BOUNDARY:
- pos = startOfLine(VisiblePosition(m_start, m_affinity), DOWNSTREAM);
+ pos = startOfLine(VisiblePosition(m_start, m_affinity));
break;
case PARAGRAPH_BOUNDARY:
pos = startOfParagraph(VisiblePosition(m_start, m_affinity));
pos = previousWordPosition(VisiblePosition(m_extent, m_affinity));
break;
case PARAGRAPH:
- pos = previousParagraphPosition(VisiblePosition(m_start, m_affinity), m_affinity, xPosForVerticalArrowNavigation(START, isRange()));
+ pos = previousParagraphPosition(VisiblePosition(m_start, m_affinity), xPosForVerticalArrowNavigation(START, isRange()));
break;
case LINE:
- pos = previousLinePosition(VisiblePosition(m_start, m_affinity), m_affinity, xPosForVerticalArrowNavigation(START, isRange()));
+ pos = previousLinePosition(VisiblePosition(m_start, m_affinity), xPosForVerticalArrowNavigation(START, isRange()));
break;
case LINE_BOUNDARY:
- pos = startOfLine(VisiblePosition(m_start, m_affinity), DOWNSTREAM);
+ pos = startOfLine(VisiblePosition(m_start, m_affinity));
break;
case PARAGRAPH_BOUNDARY:
pos = startOfParagraph(VisiblePosition(m_start, m_affinity));
if (up)
verticalDistance = -verticalDistance;
+ // can dump this UPSTREAM when we have m_extentAffinity
m_affinity = UPSTREAM;
setModifyBias(alter, up ? BACKWARD : FORWARD);
VisiblePosition result;
VisiblePosition next;
for (VisiblePosition p = pos; ; p = next) {
- next = (up ? previousLinePosition : nextLinePosition)(p, m_affinity, xPos);
+ next = (up ? previousLinePosition : nextLinePosition)(p, xPos);
if (next.isNull() || next == p)
break;
int nextY;
VisiblePosition start = m_baseIsStart ? VisiblePosition(m_base, m_affinity) : VisiblePosition(m_extent, m_affinity);
VisiblePosition end = m_baseIsStart ? VisiblePosition(m_extent, m_affinity) : VisiblePosition(m_base, m_affinity);
EWordSide side = RightWordIfOnBoundary;
- if (isEndOfDocument(start) || (isEndOfLine(start, m_affinity) && !isStartOfLine(start, m_affinity) && !isEndOfParagraph(start)))
+ if (isEndOfDocument(start) || (isEndOfLine(start) && !isStartOfLine(start) && !isEndOfParagraph(start)))
side = LeftWordIfOnBoundary;
m_start = startOfWord(start, side).deepEquivalent();
side = RightWordIfOnBoundary;
- if (isEndOfDocument(end) || (isEndOfLine(end, m_affinity) && !isStartOfLine(end, m_affinity) && !isEndOfParagraph(end)))
+ if (isEndOfDocument(end) || (isEndOfLine(end) && !isStartOfLine(end) && !isEndOfParagraph(end)))
side = LeftWordIfOnBoundary;
m_end = endOfWord(end, side).deepEquivalent();
case LINE:
case LINE_BOUNDARY:
if (m_baseIsStart) {
- m_start = startOfLine(VisiblePosition(m_base, m_affinity), m_affinity).deepEquivalent();
- m_end = endOfLine(VisiblePosition(m_extent, m_affinity), m_affinity, IncludeLineBreak).deepEquivalent();
+ m_start = startOfLine(VisiblePosition(m_base, m_affinity)).deepEquivalent();
+ m_end = endOfLine(VisiblePosition(m_extent, m_affinity), IncludeLineBreak).deepEquivalent();
} else {
- m_start = startOfLine(VisiblePosition(m_extent, m_affinity), m_affinity).deepEquivalent();
- m_end = endOfLine(VisiblePosition(m_base, m_affinity), m_affinity, IncludeLineBreak).deepEquivalent();
+ m_start = startOfLine(VisiblePosition(m_extent, m_affinity)).deepEquivalent();
+ m_end = endOfLine(VisiblePosition(m_base, m_affinity), IncludeLineBreak).deepEquivalent();
}
break;
case PARAGRAPH:
if (m_baseIsStart) {
VisiblePosition pos(m_base, m_affinity);
- if (isStartOfLine(pos, m_affinity) && isEndOfDocument(pos))
+ if (isStartOfLine(pos) && isEndOfDocument(pos))
pos = pos.previous();
m_start = startOfParagraph(pos).deepEquivalent();
m_end = endOfParagraph(VisiblePosition(m_extent, m_affinity), IncludeLineBreak).deepEquivalent();
//
// Handle leading and trailing whitespace, as well as smart delete adjustments to the selection
//
- m_leadingWhitespace = m_upstreamStart.leadingWhitespacePosition();
+ m_leadingWhitespace = m_upstreamStart.leadingWhitespacePosition(m_selectionToDelete.startAffinity());
bool hasLeadingWhitespaceBeforeAdjustment = m_leadingWhitespace.isNotNull();
if (m_smartDelete && hasLeadingWhitespaceBeforeAdjustment) {
- Position pos = VisiblePosition(start, m_selectionToDelete.startAffinity()).previous().deepEquivalent();
+ VisiblePosition visiblePos = VisiblePosition(start, m_selectionToDelete.startAffinity()).previous();
+ Position pos = visiblePos.deepEquivalent();
// Expand out one character upstream for smart delete and recalculate
// positions based on this change.
m_upstreamStart = pos.upstream(StayInBlock);
m_downstreamStart = pos.downstream(StayInBlock);
- m_leadingWhitespace = m_upstreamStart.leadingWhitespacePosition();
+ m_leadingWhitespace = m_upstreamStart.leadingWhitespacePosition(visiblePos.affinity());
}
- m_trailingWhitespace = m_downstreamEnd.trailingWhitespacePosition();
+ m_trailingWhitespace = m_downstreamEnd.trailingWhitespacePosition(VP_DEFAULT_AFFINITY);
// Note: trailing whitespace is only considered for smart delete if there is no leading
// whitespace, as in the case where you double-click the first word of a paragraph.
if (m_smartDelete && !hasLeadingWhitespaceBeforeAdjustment && m_trailingWhitespace.isNotNull()) {
Position pos = VisiblePosition(end, m_selectionToDelete.endAffinity()).next().deepEquivalent();
m_upstreamEnd = pos.upstream(StayInBlock);
m_downstreamEnd = pos.downstream(StayInBlock);
- m_trailingWhitespace = m_downstreamEnd.trailingWhitespacePosition();
+ m_trailingWhitespace = m_downstreamEnd.trailingWhitespacePosition(VP_DEFAULT_AFFINITY);
}
m_trailingWhitespaceValid = true;
//
VisiblePosition visibleEnd(end, m_selectionToDelete.endAffinity());
if (isFirstVisiblePositionInParagraph(visibleEnd) || isLastVisiblePositionInParagraph(visibleEnd)) {
- Position previousLineStart = previousLinePosition(visibleEnd, DOWNSTREAM, 0).deepEquivalent();
+ Position previousLineStart = previousLinePosition(visibleEnd, 0).deepEquivalent();
if (previousLineStart.isNull() || RangeImpl::compareBoundaryPoints(previousLineStart, m_downstreamStart) >= 0)
m_mergeBlocksAfterDelete = false;
}
int exception;
rangeAroundNode->selectNode(nodeToInsert, exception);
- setEndingSelection(Selection(rangeAroundNode, DOWNSTREAM, UPSTREAM));
+ // affinity is not really important since this is a temp selection
+ // just for calling applyStyle
+ setEndingSelection(Selection(rangeAroundNode, khtml::SEL_DEFAULT_AFFINITY, khtml::SEL_DEFAULT_AFFINITY));
applyStyle(typingStyle);
setEndingSelection(selectionBeforeStyle);
}
// Make sure we do not cause a rendered space to become unrendered.
- Position leadingWhitespace = pos.leadingWhitespacePosition();
+ // FIXME: We need the affinity for pos, but pos.downstream(StayInBlock) does not give it
+ Position leadingWhitespace = pos.leadingWhitespacePosition(VP_DEFAULT_AFFINITY);
if (leadingWhitespace.isNotNull()) {
TextImpl *textNode = static_cast<TextImpl *>(leadingWhitespace.node());
replaceTextInNode(textNode, leadingWhitespace.offset(), 1, nonBreakingSpaceString());
// Delete any insignificant text that could get in the way of whitespace turning
// out correctly after the insertion.
- deleteInsignificantTextDownstream(endingSelection().end().trailingWhitespacePosition());
+ selection = endingSelection();
+ deleteInsignificantTextDownstream(selection.end().trailingWhitespacePosition(selection.endAffinity()));
// Make sure the document is set up to receive text
Position startPosition = prepareForTextInsertion(adjustDownstream);
// check whether to "smart replace" needs to add leading and/or trailing space
bool addLeadingSpace = false;
bool addTrailingSpace = false;
+ // FIXME: We need the affinity for startPos and endPos, but Position::downstream
+ // and Position::upstream do not give it
if (m_smartReplace) {
- addLeadingSpace = startPos.leadingWhitespacePosition().isNotNull();
+ addLeadingSpace = startPos.leadingWhitespacePosition(VP_DEFAULT_AFFINITY).isNotNull();
if (addLeadingSpace) {
QChar previousChar = VisiblePosition(startPos, VP_DEFAULT_AFFINITY).previous().character();
if (!previousChar.isNull()) {
addLeadingSpace = !part->isCharacterSmartReplaceExempt(previousChar, true);
}
}
- addTrailingSpace = endPos.trailingWhitespacePosition().isNotNull();
+ addTrailingSpace = endPos.trailingWhitespacePosition(VP_DEFAULT_AFFINITY).isNotNull();
if (addTrailingSpace) {
QChar thisChar = VisiblePosition(endPos, VP_DEFAULT_AFFINITY).character();
if (!thisChar.isNull()) {
int exceptionCode = 0;
rangeAroundNode->selectNode(node, exceptionCode);
ASSERT(exceptionCode == 0);
- setEndingSelection(Selection(rangeAroundNode, DOWNSTREAM, UPSTREAM));
+ // affinity is not really important since this is a temp selection
+ // just for calling applyStyle
+ setEndingSelection(Selection(rangeAroundNode, SEL_DEFAULT_AFFINITY, SEL_DEFAULT_AFFINITY));
applyStyle(desiredStyle);
rangeAroundNode->deref();
}
pos = nextWordPosition(pos);
break;
case PARAGRAPH:
- pos = nextParagraphPosition(pos, m_affinity, xPosForVerticalArrowNavigation(EXTENT));
+ pos = nextParagraphPosition(pos, xPosForVerticalArrowNavigation(EXTENT));
break;
case LINE:
- pos = nextLinePosition(pos, m_affinity, xPosForVerticalArrowNavigation(EXTENT));
+ pos = nextLinePosition(pos, xPosForVerticalArrowNavigation(EXTENT));
break;
case LINE_BOUNDARY:
- pos = endOfLine(VisiblePosition(m_end, m_affinity), UPSTREAM);
+ pos = endOfLine(VisiblePosition(m_end, m_affinity));
break;
case PARAGRAPH_BOUNDARY:
pos = endOfParagraph(VisiblePosition(m_end, m_affinity));
pos = nextWordPosition(VisiblePosition(m_extent, m_affinity));
break;
case PARAGRAPH:
- pos = nextParagraphPosition(VisiblePosition(m_end, m_affinity), m_affinity, xPosForVerticalArrowNavigation(END, isRange()));
+ pos = nextParagraphPosition(VisiblePosition(m_end, m_affinity), xPosForVerticalArrowNavigation(END, isRange()));
break;
case LINE: {
- // This somewhat complicated code is needed to handle the case where there is a
- // whole line selected (like when the user clicks at the start of a line and hits shift+down-arrow),
- // and then hits an (unshifted) down arrow. Since the whole-line selection considers its
- // ending point to be the start of the next line, it may be necessary to juggle the
- // position to use as the VisiblePosition to pass to nextLinePosition(). If this juggling
- // is not done, you can wind up skipping a line. See these two bugs for more information:
- // <rdar://problem/3875618> REGRESSION (Mail): Hitting down arrow with full line selected skips line (br case)
- // <rdar://problem/3875641> REGRESSION (Mail): Hitting down arrow with full line selected skips line (div case)
- if (isCaret()) {
- pos = VisiblePosition(m_end, m_affinity);
- } else if (isRange()) {
- Position p(m_end.upstream());
- if (p.node()->id() == ID_BR)
- pos = VisiblePosition(Position(p.node(), 0), UPSTREAM);
- else
- pos = VisiblePosition(p, UPSTREAM);
- }
- pos = nextLinePosition(pos, m_affinity, xPosForVerticalArrowNavigation(END, isRange()));
+ // down-arrowing from a range selection that ends at the start of a line needs
+ // to leave the selection at that line start (no need to call nextLinePosition!)
+ pos = VisiblePosition(m_end, m_affinity);
+ if (!isRange() || !isStartOfLine(pos))
+ pos = nextLinePosition(pos, xPosForVerticalArrowNavigation(END, isRange()));
break;
}
case LINE_BOUNDARY:
- pos = endOfLine(VisiblePosition(m_end, m_affinity), UPSTREAM);
+ pos = endOfLine(VisiblePosition(m_end, m_affinity));
break;
case PARAGRAPH_BOUNDARY:
pos = endOfParagraph(VisiblePosition(m_end, m_affinity));
pos = previousWordPosition(pos);
break;
case PARAGRAPH:
- pos = previousParagraphPosition(pos, m_affinity, xPosForVerticalArrowNavigation(EXTENT));
+ pos = previousParagraphPosition(pos, xPosForVerticalArrowNavigation(EXTENT));
break;
case LINE:
- pos = previousLinePosition(pos, m_affinity, xPosForVerticalArrowNavigation(EXTENT));
+ pos = previousLinePosition(pos, xPosForVerticalArrowNavigation(EXTENT));
break;
case LINE_BOUNDARY:
- pos = startOfLine(VisiblePosition(m_start, m_affinity), DOWNSTREAM);
+ pos = startOfLine(VisiblePosition(m_start, m_affinity));
break;
case PARAGRAPH_BOUNDARY:
pos = startOfParagraph(VisiblePosition(m_start, m_affinity));
pos = previousWordPosition(VisiblePosition(m_extent, m_affinity));
break;
case PARAGRAPH:
- pos = previousParagraphPosition(VisiblePosition(m_start, m_affinity), m_affinity, xPosForVerticalArrowNavigation(START, isRange()));
+ pos = previousParagraphPosition(VisiblePosition(m_start, m_affinity), xPosForVerticalArrowNavigation(START, isRange()));
break;
case LINE:
- pos = previousLinePosition(VisiblePosition(m_start, m_affinity), m_affinity, xPosForVerticalArrowNavigation(START, isRange()));
+ pos = previousLinePosition(VisiblePosition(m_start, m_affinity), xPosForVerticalArrowNavigation(START, isRange()));
break;
case LINE_BOUNDARY:
- pos = startOfLine(VisiblePosition(m_start, m_affinity), DOWNSTREAM);
+ pos = startOfLine(VisiblePosition(m_start, m_affinity));
break;
case PARAGRAPH_BOUNDARY:
pos = startOfParagraph(VisiblePosition(m_start, m_affinity));
if (up)
verticalDistance = -verticalDistance;
+ // can dump this UPSTREAM when we have m_extentAffinity
m_affinity = UPSTREAM;
setModifyBias(alter, up ? BACKWARD : FORWARD);
VisiblePosition result;
VisiblePosition next;
for (VisiblePosition p = pos; ; p = next) {
- next = (up ? previousLinePosition : nextLinePosition)(p, m_affinity, xPos);
+ next = (up ? previousLinePosition : nextLinePosition)(p, xPos);
if (next.isNull() || next == p)
break;
int nextY;
VisiblePosition start = m_baseIsStart ? VisiblePosition(m_base, m_affinity) : VisiblePosition(m_extent, m_affinity);
VisiblePosition end = m_baseIsStart ? VisiblePosition(m_extent, m_affinity) : VisiblePosition(m_base, m_affinity);
EWordSide side = RightWordIfOnBoundary;
- if (isEndOfDocument(start) || (isEndOfLine(start, m_affinity) && !isStartOfLine(start, m_affinity) && !isEndOfParagraph(start)))
+ if (isEndOfDocument(start) || (isEndOfLine(start) && !isStartOfLine(start) && !isEndOfParagraph(start)))
side = LeftWordIfOnBoundary;
m_start = startOfWord(start, side).deepEquivalent();
side = RightWordIfOnBoundary;
- if (isEndOfDocument(end) || (isEndOfLine(end, m_affinity) && !isStartOfLine(end, m_affinity) && !isEndOfParagraph(end)))
+ if (isEndOfDocument(end) || (isEndOfLine(end) && !isStartOfLine(end) && !isEndOfParagraph(end)))
side = LeftWordIfOnBoundary;
m_end = endOfWord(end, side).deepEquivalent();
case LINE:
case LINE_BOUNDARY:
if (m_baseIsStart) {
- m_start = startOfLine(VisiblePosition(m_base, m_affinity), m_affinity).deepEquivalent();
- m_end = endOfLine(VisiblePosition(m_extent, m_affinity), m_affinity, IncludeLineBreak).deepEquivalent();
+ m_start = startOfLine(VisiblePosition(m_base, m_affinity)).deepEquivalent();
+ m_end = endOfLine(VisiblePosition(m_extent, m_affinity), IncludeLineBreak).deepEquivalent();
} else {
- m_start = startOfLine(VisiblePosition(m_extent, m_affinity), m_affinity).deepEquivalent();
- m_end = endOfLine(VisiblePosition(m_base, m_affinity), m_affinity, IncludeLineBreak).deepEquivalent();
+ m_start = startOfLine(VisiblePosition(m_extent, m_affinity)).deepEquivalent();
+ m_end = endOfLine(VisiblePosition(m_base, m_affinity), IncludeLineBreak).deepEquivalent();
}
break;
case PARAGRAPH:
if (m_baseIsStart) {
VisiblePosition pos(m_base, m_affinity);
- if (isStartOfLine(pos, m_affinity) && isEndOfDocument(pos))
+ if (isStartOfLine(pos) && isEndOfDocument(pos))
pos = pos.previous();
m_start = startOfParagraph(pos).deepEquivalent();
m_end = endOfParagraph(VisiblePosition(m_extent, m_affinity), IncludeLineBreak).deepEquivalent();
RenderObject *r2 = p2.node()->renderer();
if (r1->isBlockFlow() || r2->isBlockFlow())
return r1 == r2 ? false : true;
- InlineBox *b1 = r1 ? r1->inlineBox(p1.offset()) : 0;
- InlineBox *b2 = r2 ? r2->inlineBox(p2.offset()) : 0;
+ InlineBox *b1 = r1 ? r1->inlineBox(p1.offset(), pos1.affinity()) : 0;
+ InlineBox *b2 = r2 ? r2->inlineBox(p2.offset(), pos2.affinity()) : 0;
return (b1 && b2 && b1->root() != b2->root());
}
// ---------
-static RootInlineBox *rootBoxForLine(const VisiblePosition &c, EAffinity affinity)
+static RootInlineBox *rootBoxForLine(const VisiblePosition &c)
{
Position p = c.deepEquivalent();
NodeImpl *node = p.node();
if (!renderer)
return 0;
- InlineBox *box = renderer->inlineBox(p.offset(), affinity);
+ InlineBox *box = renderer->inlineBox(p.offset(), c.affinity());
if (!box)
return 0;
return box->root();
}
-VisiblePosition startOfLine(const VisiblePosition &c, EAffinity affinity)
+VisiblePosition startOfLine(const VisiblePosition &c)
{
- RootInlineBox *rootBox = rootBoxForLine(c, affinity);
+ RootInlineBox *rootBox = rootBoxForLine(c);
if (!rootBox)
return VisiblePosition();
InlineTextBox *startTextBox = static_cast<InlineTextBox *>(startBox);
startOffset = startTextBox->m_start;
}
- return VisiblePosition(startNode, startOffset, affinity);
+ return VisiblePosition(startNode, startOffset, DOWNSTREAM);
}
-VisiblePosition endOfLine(const VisiblePosition &c, EAffinity affinity, EIncludeLineBreak includeLineBreak)
+VisiblePosition endOfLine(const VisiblePosition &c, EIncludeLineBreak includeLineBreak)
{
// FIXME: Need to implement the "include line break" version.
assert(includeLineBreak == DoNotIncludeLineBreak);
- RootInlineBox *rootBox = rootBoxForLine(c, affinity);
+ RootInlineBox *rootBox = rootBoxForLine(c);
if (!rootBox)
return VisiblePosition();
long endOffset = 1;
if (endNode->id() == ID_BR) {
endOffset = 0;
- }
- else if (endBox->isInlineTextBox()) {
+ } else if (endBox->isInlineTextBox()) {
InlineTextBox *endTextBox = static_cast<InlineTextBox *>(endBox);
endOffset = endTextBox->m_start + endTextBox->m_len;
}
- return VisiblePosition(endNode, endOffset, affinity);
+
+ // generate VisiblePosition with correct affinity
+ VisiblePosition result = VisiblePosition(endNode, endOffset, DOWNSTREAM);
+ VisiblePosition temp = result;
+ temp.setAffinity(UPSTREAM);
+ if (visiblePositionsOnDifferentLines(temp, result))
+ result.setAffinity(UPSTREAM);
+
+ return result;
}
-bool inSameLine(const VisiblePosition &a, EAffinity aa, const VisiblePosition &b, EAffinity ab)
+bool inSameLine(const VisiblePosition &a, const VisiblePosition &b)
{
- return a.isNotNull() && startOfLine(a, aa) == startOfLine(b, ab);
+ return a.isNotNull() && startOfLine(a) == startOfLine(b);
}
-bool isStartOfLine(const VisiblePosition &p, EAffinity affinity)
+bool isStartOfLine(const VisiblePosition &p)
{
- return p.isNotNull() && p == startOfLine(p, affinity);
+ return p.isNotNull() && p == startOfLine(p);
}
-bool isEndOfLine(const VisiblePosition &p, EAffinity affinity)
+bool isEndOfLine(const VisiblePosition &p)
{
- return p.isNotNull() && p == endOfLine(p, affinity, DoNotIncludeLineBreak);
+ return p.isNotNull() && p == endOfLine(p, DoNotIncludeLineBreak);
}
-VisiblePosition previousLinePosition(const VisiblePosition &c, EAffinity affinity, int x)
+VisiblePosition previousLinePosition(const VisiblePosition &c, int x)
{
- Position p = affinity == UPSTREAM ? c.deepEquivalent() : c.downstreamDeepEquivalent();
+ Position p = c.affinity() == UPSTREAM ? c.deepEquivalent() : c.downstreamDeepEquivalent();
NodeImpl *node = p.node();
if (!node)
return VisiblePosition();
RenderBlock *containingBlock = 0;
RootInlineBox *root = 0;
- InlineBox *box = renderer->inlineBox(p.offset(), affinity);
+ InlineBox *box = renderer->inlineBox(p.offset(), c.affinity());
if (box) {
root = box->root()->prevRootBox();
if (root)
int absx, absy;
containingBlock->absolutePosition(absx, absy);
RenderObject *renderer = root->closestLeafChildForXPos(x, absx)->object();
- EAffinity posAffinity;
- Position pos = renderer->positionForCoordinates(x, absy + root->topOverflow(), &posAffinity);
- return VisiblePosition(pos, posAffinity);
+ return renderer->positionForCoordinates(x, absy + root->topOverflow());
}
// Could not find a previous line. This means we must already be on the first line.
return VisiblePosition(node->rootEditableElement(), 0, DOWNSTREAM);
}
-VisiblePosition nextLinePosition(const VisiblePosition &c, EAffinity affinity, int x)
+VisiblePosition nextLinePosition(const VisiblePosition &c, int x)
{
- Position p = affinity == UPSTREAM ? c.deepEquivalent() : c.downstreamDeepEquivalent();
+ Position p = c.affinity() == UPSTREAM ? c.deepEquivalent() : c.downstreamDeepEquivalent();
NodeImpl *node = p.node();
if (!node)
return VisiblePosition();
RenderBlock *containingBlock = 0;
RootInlineBox *root = 0;
- InlineBox *box = renderer->inlineBox(p.offset(), affinity);
+ InlineBox *box = renderer->inlineBox(p.offset(), c.affinity());
if (box) {
root = box->root()->nextRootBox();
if (root)
int absx, absy;
containingBlock->absolutePosition(absx, absy);
RenderObject *renderer = root->closestLeafChildForXPos(x, absx)->object();
- EAffinity posAffinity;
- Position pos = renderer->positionForCoordinates(x, absy + root->topOverflow(), &posAffinity);
- return VisiblePosition(pos, posAffinity);
+ return renderer->positionForCoordinates(x, absy + root->topOverflow());
}
// Could not find a next line. This means we must already be on the last line.
// Move to the end of the content in this block, which effectively moves us
// to the end of the line we're on.
ElementImpl *rootElement = node->rootEditableElement();
- return VisiblePosition(rootElement, rootElement ? rootElement->childNodeCount() : 0, affinity);
+ return VisiblePosition(rootElement, rootElement ? rootElement->childNodeCount() : 0, DOWNSTREAM);
}
// ---------
return nextSentenceFromIndex(characters, length, length, false);
}
-VisiblePosition previousSentencePosition(const VisiblePosition &c, EAffinity, int x)
+VisiblePosition previousSentencePosition(const VisiblePosition &c, int x)
{
return previousBoundary(c, previousSentencePositionBoundary);
}
return nextSentenceFromIndex(characters, length, 0, true);
}
-VisiblePosition nextSentencePosition(const VisiblePosition &c, EAffinity, int x)
+VisiblePosition nextSentencePosition(const VisiblePosition &c, int x)
{
return nextBoundary(c, nextSentencePositionBoundary);
}
return pos.isNotNull() && pos == endOfParagraph(pos, DoNotIncludeLineBreak);
}
-VisiblePosition previousParagraphPosition(const VisiblePosition &p, EAffinity a, int x)
+VisiblePosition previousParagraphPosition(const VisiblePosition &p, int x)
{
VisiblePosition pos = p;
do {
- VisiblePosition n = previousLinePosition(pos, a, x);
+ VisiblePosition n = previousLinePosition(pos, x);
if (n.isNull() || n == pos) {
return p;
}
return pos;
}
-VisiblePosition nextParagraphPosition(const VisiblePosition &p, EAffinity a, int x)
+VisiblePosition nextParagraphPosition(const VisiblePosition &p, int x)
{
VisiblePosition pos = p;
do {
- VisiblePosition n = nextLinePosition(pos, a, x);
+ VisiblePosition n = nextLinePosition(pos, x);
if (n.isNull() || n == pos) {
return p;
}
VisiblePosition nextWordPosition(const VisiblePosition &);
// lines
-VisiblePosition startOfLine(const VisiblePosition &, EAffinity);
-VisiblePosition endOfLine(const VisiblePosition &, EAffinity, EIncludeLineBreak = DoNotIncludeLineBreak);
-VisiblePosition previousLinePosition(const VisiblePosition &, EAffinity, int x);
-VisiblePosition nextLinePosition(const VisiblePosition &, EAffinity, int x);
-bool inSameLine(const VisiblePosition &, EAffinity, const VisiblePosition &, EAffinity);
-bool isStartOfLine(const VisiblePosition &, EAffinity);
-bool isEndOfLine(const VisiblePosition &, EAffinity);
+VisiblePosition startOfLine(const VisiblePosition &);
+VisiblePosition endOfLine(const VisiblePosition &, EIncludeLineBreak = DoNotIncludeLineBreak);
+VisiblePosition previousLinePosition(const VisiblePosition &, int x);
+VisiblePosition nextLinePosition(const VisiblePosition &, int x);
+bool inSameLine(const VisiblePosition &, const VisiblePosition &);
+bool isStartOfLine(const VisiblePosition &);
+bool isEndOfLine(const VisiblePosition &);
// sentences
VisiblePosition startOfSentence(const VisiblePosition &);
// paragraphs (perhaps a misnomer, can be divided by line break elements)
VisiblePosition startOfParagraph(const VisiblePosition &);
VisiblePosition endOfParagraph(const VisiblePosition &, EIncludeLineBreak = DoNotIncludeLineBreak);
-VisiblePosition previousParagraphPosition(const VisiblePosition &, EAffinity, int x);
-VisiblePosition nextParagraphPosition(const VisiblePosition &, EAffinity, int x);
+VisiblePosition previousParagraphPosition(const VisiblePosition &, int x);
+VisiblePosition nextParagraphPosition(const VisiblePosition &, int x);
bool inSameParagraph(const VisiblePosition &, const VisiblePosition &);
bool isStartOfParagraph(const VisiblePosition &);
bool isEndOfParagraph(const VisiblePosition &);
if (inner.nodeType() == Node::TEXT_NODE)
inner = inner.parentNode();
if (inner.handle()->renderer())
- pos = inner.handle()->renderer()->positionForCoordinates(m_x, m_y);
+ pos = inner.handle()->renderer()->positionForCoordinates(m_x, m_y).deepEquivalent();
}
return pos.offset();
}
if (!innerNode || !innerNode->renderer())
return false;
- Position pos(innerNode->renderer()->positionForCoordinates(x, y));
+ Position pos(innerNode->renderer()->positionForCoordinates(x, y).deepEquivalent());
if (pos.isNull())
return false;
Selection selection;
if (!innerNode.isNull() && innerNode.handle()->renderer() && innerNode.handle()->renderer()->shouldSelect()) {
- EAffinity affinity;
- Position pos(innerNode.handle()->renderer()->positionForCoordinates(x, y, &affinity));
+ VisiblePosition pos(innerNode.handle()->renderer()->positionForCoordinates(x, y));
if (pos.isNotNull()) {
- selection.moveTo(pos, affinity);
+ selection.moveTo(pos);
selection.expandUsingGranularity(WORD);
}
}
if (mouse->button() == LeftButton && !innerNode.isNull() && innerNode.handle()->renderer() &&
innerNode.handle()->renderer()->shouldSelect()) {
- EAffinity affinity;
- Position pos(innerNode.handle()->renderer()->positionForCoordinates(event->x(), event->y(), &affinity));
+ VisiblePosition pos(innerNode.handle()->renderer()->positionForCoordinates(event->x(), event->y()));
if (pos.isNotNull()) {
- selection.moveTo(pos, affinity);
+ selection.moveTo(pos);
selection.expandUsingGranularity(PARAGRAPH);
}
}
if (!extendSelection && isPointInsideSelection(event->x(), event->y())) {
return;
}
- EAffinity affinity;
- Position pos(innerNode.handle()->renderer()->positionForCoordinates(event->x(), event->y(), &affinity));
- if (pos.isNull())
- pos = Position(innerNode.handle(), innerNode.handle()->caretMinOffset());
+ VisiblePosition visiblePos(innerNode.handle()->renderer()->positionForCoordinates(event->x(), event->y()));
+ if (visiblePos.isNull())
+ visiblePos = VisiblePosition(innerNode.handle(), innerNode.handle()->caretMinOffset(), khtml::DOWNSTREAM);
+ Position pos = visiblePos.deepEquivalent();
+
sel = selection();
if (extendSelection && sel.isCaretOrRange()) {
sel.clearModifyBias();
Position start = sel.start();
short before = RangeImpl::compareBoundaryPoints(pos.node(), pos.offset(), start.node(), start.offset());
if (before <= 0) {
- sel.setBaseAndExtent(pos, affinity, sel.end(), sel.endAffinity());
+ sel.setBaseAndExtent(pos, visiblePos.affinity(), sel.end(), sel.endAffinity());
} else {
- sel.setBaseAndExtent(start, sel.startAffinity(), pos, affinity);
+ sel.setBaseAndExtent(start, sel.startAffinity(), pos, visiblePos.affinity());
}
if (d->m_selectionGranularity != CHARACTER) {
}
d->m_beganSelectingText = true;
} else {
- sel = Selection(pos, affinity);
+ sel = Selection(visiblePos);
d->m_selectionGranularity = CHARACTER;
}
}
return;
// handle making selection
- EAffinity affinity;
- Position pos(innerNode.handle()->renderer()->positionForCoordinates(event->x(), event->y(), &affinity));
+ VisiblePosition pos(innerNode.handle()->renderer()->positionForCoordinates(event->x(), event->y()));
// Don't modify the selection if we're not on a node.
if (pos.isNull())
sel.clearModifyBias();
if (!d->m_beganSelectingText) {
d->m_beganSelectingText = true;
- sel.moveTo(pos, affinity);
+ sel.moveTo(pos);
}
- sel.setExtent(pos, affinity);
+ sel.setExtent(pos);
if (d->m_selectionGranularity != CHARACTER) {
sel.expandUsingGranularity(d->m_selectionGranularity);
}
Selection selection;
NodeImpl *node = d->m_selection.base().node();
if (node->isContentEditable() && node->renderer()) {
- EAffinity affinity;
- Position pos = node->renderer()->positionForCoordinates(event->x(), event->y(), &affinity);
- selection.moveTo(pos, affinity);
+ VisiblePosition pos = node->renderer()->positionForCoordinates(event->x(), event->y());
+ selection.moveTo(pos);
}
setSelection(selection);
}
return Position(node, offset);
}
-Position RenderBlock::positionForCoordinates(int _x, int _y, EAffinity *affinity)
+VisiblePosition RenderBlock::positionForCoordinates(int _x, int _y)
{
- if (affinity)
- *affinity = DOWNSTREAM;
-
if (isTable())
- return RenderFlow::positionForCoordinates(_x, _y, affinity);
+ return RenderFlow::positionForCoordinates(_x, _y);
int absx, absy;
absolutePosition(absx, absy);
if (_y < top)
// y coordinate is above block
- return positionForRenderer(firstLeafChild(), true);
+ return VisiblePosition(positionForRenderer(firstLeafChild(), true), DOWNSTREAM);
if (_y >= bottom)
// y coordinate is below block
- return positionForRenderer(lastLeafChild(), false);
+ return VisiblePosition(positionForRenderer(lastLeafChild(), false), DOWNSTREAM);
if (childrenInline()) {
if (!firstRootBox())
- return Position(element(), 0);
+ return VisiblePosition(element(), 0, DOWNSTREAM);
if (_y >= top && _y < absy + firstRootBox()->topOverflow())
// y coordinate is above first root line box
- return positionForBox(firstRootBox()->firstLeafChild(), true);
+ return VisiblePosition(positionForBox(firstRootBox()->firstLeafChild(), true), DOWNSTREAM);
// look for the closest line box in the root box which is at the passed-in y coordinate
for (RootInlineBox *root = firstRootBox(); root; root = root->nextRootBox()) {
InlineBox *closestBox = root->closestLeafChildForXPos(_x, absx);
if (closestBox) {
// pass the box a y position that is inside it
- return closestBox->object()->positionForCoordinates(_x, absy + closestBox->m_y, affinity);
+ return closestBox->object()->positionForCoordinates(_x, absy + closestBox->m_y);
}
}
}
if (lastRootBox())
// y coordinate is below last root line box
- return positionForBox(lastRootBox()->lastLeafChild(), false);
+ return VisiblePosition(positionForBox(lastRootBox()->lastLeafChild(), false), DOWNSTREAM);
- return Position(element(), 0);
+ return VisiblePosition(element(), 0, DOWNSTREAM);
}
// see if any child blocks exist at this y coordinate
else
bottom = top + contentHeight();
if (_y >= top && _y < bottom) {
- return renderer->positionForCoordinates(_x, _y, affinity);
+ return renderer->positionForCoordinates(_x, _y);
}
}
// pass along to the first child
if (firstChild())
- return firstChild()->positionForCoordinates(_x, _y, affinity);
+ return firstChild()->positionForCoordinates(_x, _y);
// still no luck...return this render object's element and offset 0
- return Position(element(), 0);
+ return VisiblePosition(element(), 0, DOWNSTREAM);
}
void RenderBlock::calcMinMaxWidth()
bool isPointInScrollbar(int x, int y, int tx, int ty);
- virtual DOM::Position positionForCoordinates(int x, int y, EAffinity * = 0);
+ virtual VisiblePosition positionForCoordinates(int x, int y);
virtual void calcMinMaxWidth();
void calcInlineMinMaxWidth();
return 1;
}
-Position RenderBR::positionForCoordinates(int _x, int _y, EAffinity *affinity)
+VisiblePosition RenderBR::positionForCoordinates(int _x, int _y)
{
- if (affinity)
- *affinity = DOWNSTREAM;
- return Position(element(), 0);
+ return VisiblePosition(element(), 0, DOWNSTREAM);
}
QRect RenderBR::caretRect(int offset, EAffinity affinity, int *extraWidthToEndOfLine)
virtual long caretMaxOffset() const;
virtual unsigned long caretMaxRenderedOffset() const;
- virtual DOM::Position positionForCoordinates(int x, int y, EAffinity * = 0);
+ virtual VisiblePosition positionForCoordinates(int x, int y);
virtual QRect caretRect(int offset, EAffinity affinity = UPSTREAM, int *extraWidthToEndOfLine = 0);
virtual InlineBox *inlineBox(long offset, EAffinity affinity = UPSTREAM);
parent()->removeLeftoverAnonymousBoxes();
}
-Position RenderContainer::positionForCoordinates(int _x, int _y, EAffinity *affinity)
+VisiblePosition RenderContainer::positionForCoordinates(int _x, int _y)
{
- if (affinity)
- *affinity = UPSTREAM;
-
// no children...return this render object's element, if there is one, and offset 0
if (!firstChild())
- return Position(element(), 0);
+ return VisiblePosition(element(), 0, DOWNSTREAM);
// look for the geometrically-closest child and pass off to that child
int min = INT_MAX;
}
if (closestRenderer)
- return closestRenderer->positionForCoordinates(_x, _y, affinity);
+ return closestRenderer->positionForCoordinates(_x, _y);
- return Position(element(), 0);
+ return VisiblePosition(element(), 0, DOWNSTREAM);
}
#undef DEBUG_LAYOUT
void updatePseudoChild(RenderStyle::PseudoId type, RenderObject* child);
- virtual DOM::Position positionForCoordinates(int x, int y, EAffinity * = 0);
+ virtual VisiblePosition positionForCoordinates(int x, int y);
private:
void setFirstChild(RenderObject *first) { m_first = first; }
return hitTestLines(info, _x, _y, _tx, _ty, hitTestAction);
}
-Position RenderInline::positionForCoordinates(int x, int y, EAffinity *affinity)
+VisiblePosition RenderInline::positionForCoordinates(int x, int y)
{
for (RenderObject *c = continuation(); c; c = c->continuation()) {
if (c->isInline() || c->firstChild())
- return c->positionForCoordinates(x, y, affinity);
+ return c->positionForCoordinates(x, y);
}
- return RenderFlow::positionForCoordinates(x, y, affinity);
+ return RenderFlow::positionForCoordinates(x, y);
}
void absoluteRects(QValueList<QRect>& rects, int _tx, int _ty);
- virtual DOM::Position positionForCoordinates(int x, int y, EAffinity * = 0);
+ virtual VisiblePosition positionForCoordinates(int x, int y);
protected:
static RenderInline* cloneInline(RenderFlow* src);
}
}
-QRect RenderObject::caretRect(int, EAffinity, int *extraWidthToEndOfLine)
+QRect RenderObject::caretRect(int offset, EAffinity affinity, int *extraWidthToEndOfLine)
{
if (extraWidthToEndOfLine)
*extraWidthToEndOfLine = 0;
arena->free(*(size_t *)base, base);
}
-Position RenderObject::positionForCoordinates(int x, int y, EAffinity *affinity)
+VisiblePosition RenderObject::positionForCoordinates(int x, int y)
{
- if (affinity)
- *affinity = UPSTREAM;
-
- return Position(element(), caretMinOffset());
+ return VisiblePosition(element(), caretMinOffset(), DOWNSTREAM);
}
bool RenderObject::mouseInside() const
#include "rendering/render_style.h"
#include "khtml_events.h"
#include "xml/dom_docimpl.h"
+#include "visible_position.h"
#include "KWQScrollBar.h"
HitTestAction hitTestAction);
void setInnerNode(NodeInfo& info);
- virtual DOM::Position positionForCoordinates(int x, int y, EAffinity * = 0);
+ virtual VisiblePosition positionForCoordinates(int x, int y);
virtual void dirtyLinesFromChangedChild(RenderObject* child, bool adding = true);
return 1;
}
-Position RenderReplaced::positionForCoordinates(int _x, int _y, EAffinity *affinity)
+VisiblePosition RenderReplaced::positionForCoordinates(int _x, int _y)
{
- if (affinity)
- *affinity = UPSTREAM;
-
InlineBox *box = inlineBoxWrapper();
if (!box)
- return Position(element(), 0);
+ return VisiblePosition(element(), 0, DOWNSTREAM);
RootInlineBox *root = box->root();
int bottom = root->nextRootBox() ? absy + root->nextRootBox()->topOverflow() : absy + root->bottomOverflow();
if (_y < top)
- return Position(element(), caretMinOffset()); // coordinates are above
+ return VisiblePosition(element(), caretMinOffset(), DOWNSTREAM); // coordinates are above
if (_y >= bottom)
- return Position(element(), caretMaxOffset()); // coordinates are below
+ return VisiblePosition(element(), caretMaxOffset(), DOWNSTREAM); // coordinates are below
if (element()) {
- if (_x <= absx + xPos() + (width() / 2)) {
- if (affinity)
- *affinity = DOWNSTREAM;
- return Position(element(), 0);
- }
- return Position(element(), 1);
+ if (_x <= absx + xPos() + (width() / 2))
+ return VisiblePosition(element(), 0, DOWNSTREAM);
+
+ return VisiblePosition(element(), 1, DOWNSTREAM);
}
- return RenderBox::positionForCoordinates(_x, _y, affinity);
+ return RenderBox::positionForCoordinates(_x, _y);
}
QRect RenderReplaced::selectionRect()
virtual long caretMinOffset() const;
virtual long caretMaxOffset() const;
virtual unsigned long caretMaxRenderedOffset() const;
- virtual DOM::Position positionForCoordinates(int x, int y, EAffinity * = 0);
+ virtual VisiblePosition positionForCoordinates(int x, int y);
virtual bool canBeSelectionLeaf() const { return true; }
virtual SelectionState selectionState() const { return m_selectionState; }
return s;
}
-Position RenderText::positionForCoordinates(int _x, int _y, EAffinity *affinity)
+VisiblePosition RenderText::positionForCoordinates(int _x, int _y)
{
- EAffinity a;
- if (!affinity)
- affinity = &a;
-
- if (!firstTextBox() || stringLength() == 0) {
- *affinity = DOWNSTREAM;
- return Position(element(), 0);
- }
+ if (!firstTextBox() || stringLength() == 0)
+ return VisiblePosition(element(), 0, DOWNSTREAM);
int absx, absy;
containingBlock()->absolutePosition(absx, absy);
if (firstTextBox() && _y < absy + firstTextBox()->root()->bottomOverflow() && _x < absx + firstTextBox()->m_x) {
// at the y coordinate of the first line or above
// and the x coordinate is to the left than the first text box left edge
- *affinity = DOWNSTREAM;
- return Position(element(), firstTextBox()->m_start);
+ return VisiblePosition(element(), firstTextBox()->m_start, DOWNSTREAM);
}
if (lastTextBox() && _y >= absy + lastTextBox()->root()->topOverflow() && _x >= absx + lastTextBox()->m_x + lastTextBox()->m_width) {
// at the y coordinate of the last line or below
// and the x coordinate is to the right than the last text box right edge
- *affinity = DOWNSTREAM;
- return Position(element(), lastTextBox()->m_start + lastTextBox()->m_len);
+ return VisiblePosition(element(), lastTextBox()->m_start + lastTextBox()->m_len, DOWNSTREAM);
}
for (InlineTextBox *box = firstTextBox(); box; box = box->nextTextBox()) {
// and the x coordinate is to the left of the right edge of this box
// check to see if position goes in this box
int offset = box->offsetForPosition(_x - absx);
- if (offset != -1) {
- *affinity = DOWNSTREAM;
- return Position(element(), offset + box->m_start);
- }
+ if (offset != -1)
+ return VisiblePosition(element(), offset + box->m_start, DOWNSTREAM);
}
else if (!box->prevOnLine() && _x < absx + box->m_x) {
// box is first on line
// and the x coordinate is to the left of the first text box left edge
- *affinity = DOWNSTREAM;
- return Position(element(), box->m_start);
+ return VisiblePosition(element(), box->m_start, DOWNSTREAM);
}
else if (!box->nextOnLine() && _x >= absx + box->m_x + box->m_width)
// box is last on line
// and the x coordinate is to the right of the last text box right edge
- *affinity = UPSTREAM;
- return Position(element(), box->m_start + box->m_len);
+ return VisiblePosition(element(), box->m_start + box->m_len, UPSTREAM);
}
}
- *affinity = DOWNSTREAM;
- return Position(element(), 0);
+ return VisiblePosition(element(), 0, DOWNSTREAM);
}
static RenderObject *firstRendererOnNextLine(InlineBox *box)
virtual void absoluteRects(QValueList<QRect>& rects, int _tx, int _ty);
- virtual DOM::Position positionForCoordinates(int x, int y, EAffinity * = 0);
+ virtual VisiblePosition positionForCoordinates(int x, int y);
unsigned int length() const { return str->l; }
QChar *text() const { return str->s; }
return result;
}
-Position Position::previousCharacterPosition() const
+Position Position::previousCharacterPosition(EAffinity affinity) const
{
if (isNull())
return Position();
NodeImpl *fromRootEditableElement = node()->rootEditableElement();
PositionIterator it(*this);
- bool atStartOfLine = isFirstVisiblePositionOnLine(VisiblePosition(*this, khtml::DOWNSTREAM));
+ bool atStartOfLine = isFirstVisiblePositionOnLine(VisiblePosition(*this, affinity));
bool rendered = inRenderedContent();
while (!it.atStart()) {
return *this;
}
-Position Position::nextCharacterPosition() const
+Position Position::nextCharacterPosition(EAffinity affinity) const
{
if (isNull())
return Position();
NodeImpl *fromRootEditableElement = node()->rootEditableElement();
PositionIterator it(*this);
- bool atEndOfLine = isLastVisiblePositionOnLine(VisiblePosition(*this, khtml::UPSTREAM));
+ bool atEndOfLine = isLastVisiblePositionOnLine(VisiblePosition(*this, affinity));
bool rendered = inRenderedContent();
while (!it.atEnd()) {
return c.isSpace() && c != nonBreakingSpace;
}
-Position Position::leadingWhitespacePosition() const
+Position Position::leadingWhitespacePosition(EAffinity affinity) const
{
if (isNull())
return Position();
if (upstream(StayInBlock).node()->id() == ID_BR)
return Position();
- Position prev = previousCharacterPosition();
+ Position prev = previousCharacterPosition(affinity);
if (prev != *this && prev.node()->inSameContainingBlockFlowElement(node()) && prev.node()->isTextNode()) {
DOMString string = static_cast<TextImpl *>(prev.node())->data();
if (isWS(string[prev.offset()]))
return Position();
}
-Position Position::trailingWhitespacePosition() const
+Position Position::trailingWhitespacePosition(EAffinity affinity) const
{
if (isNull())
return Position();
if (downstream(StayInBlock).node()->id() == ID_BR)
return Position();
- Position next = nextCharacterPosition();
+ Position next = nextCharacterPosition(affinity);
if (next != *this && next.node()->inSameContainingBlockFlowElement(node()) && next.node()->isTextNode()) {
DOMString string = static_cast<TextImpl *>(next.node())->data();
if (isWS(string[0]))
ElementImpl *element() const;
CSSComputedStyleDeclarationImpl *computedStyle() const;
- Position leadingWhitespacePosition() const;
- Position trailingWhitespacePosition() const;
+ Position leadingWhitespacePosition(khtml::EAffinity affinity) const;
+ Position trailingWhitespacePosition(khtml::EAffinity affinity) const;
// These functions only consider leaf nodes, and if stayInBlock is true, blocks.
// Hence, the results from these functions are idiosyncratic, and until you
bool inRenderedText() const;
- Position previousCharacterPosition() const;
- Position nextCharacterPosition() const;
+ Position previousCharacterPosition(khtml::EAffinity affinity) const;
+ Position nextCharacterPosition(khtml::EAffinity affinity) const;
NodeImpl *m_node;
long m_offset;
if (!docPart)
return nil;
- // FIXME: should use startOfDocument and endOfDocument here
- EAffinity startAffinity;
- Position startPos = m_renderer->positionForCoordinates (0, 0, &startAffinity);
- EAffinity endAffinity;
- Position endPos = m_renderer->positionForCoordinates (LONG_MAX, LONG_MAX, &endAffinity);
-
- VisiblePosition startVisiblePosition = VisiblePosition(startPos, startAffinity);
- VisiblePosition endVisiblePosition = VisiblePosition(endPos, endAffinity);
+ // FIXME: should use startOfDocument and endOfDocument (or rangeForDocument?) here
+ VisiblePosition startVisiblePosition = m_renderer->positionForCoordinates (0, 0);
+ VisiblePosition endVisiblePosition = m_renderer->positionForCoordinates (LONG_MAX, LONG_MAX);
QString qString = plainText(makeRange(startVisiblePosition, endVisiblePosition));
// transform it to a CFString and return that
if ([attributeName isEqualToString: (NSString *) kAXStartTextMarkerAttribute]) {
// FIXME: should use startOfDocument here
- EAffinity startAffinity;
- Position startPos = [self topRenderer]->positionForCoordinates (0, 0, &startAffinity);
- return (id) [self textMarkerForVisiblePosition: VisiblePosition(startPos, startAffinity)];
+ VisiblePosition startPos = [self topRenderer]->positionForCoordinates (0, 0);
+ return (id) [self textMarkerForVisiblePosition: startPos];
}
if ([attributeName isEqualToString: (NSString *) kAXEndTextMarkerAttribute]) {
// FIXME: should use endOfDocument here
- EAffinity endAffinity;
- Position endPos = [self topRenderer]->positionForCoordinates (LONG_MAX, LONG_MAX, &endAffinity);
- return (id) [self textMarkerForVisiblePosition: VisiblePosition(endPos, endAffinity)];
+ VisiblePosition endPos = [self topRenderer]->positionForCoordinates (LONG_MAX, LONG_MAX);
+ return (id) [self textMarkerForVisiblePosition: endPos];
}
#endif
while (visiblePos.isNotNull() && visiblePos != savedVisiblePos) {
lineCount += 1;
savedVisiblePos = visiblePos;
- visiblePos = previousLinePosition(visiblePos, khtml::DOWNSTREAM, 0);
+ visiblePos = previousLinePosition(visiblePos, 0);
}
return [NSNumber numberWithUnsignedInt:lineCount];
// iterate over the lines
// NOTE: BUG this is wrong when lineNumber is lineCount+1, because nextLinePosition takes you to the
// last offset of the last line
- EAffinity affinity;
- Position pos = [self topRenderer]->positionForCoordinates (0, 0, &affinity);
- VisiblePosition visiblePos = VisiblePosition(pos, affinity);
+ VisiblePosition visiblePos = [self topRenderer]->positionForCoordinates (0, 0);
VisiblePosition savedVisiblePos;
while (--lineCount != 0) {
savedVisiblePos = visiblePos;
- visiblePos = nextLinePosition(visiblePos, visiblePos.affinity(), 0);
+ visiblePos = nextLinePosition(visiblePos, 0);
if (visiblePos.isNull() || visiblePos == savedVisiblePos)
return nil;
}
NSPoint windowpoint = [[view window] convertScreenToBase: screenpoint];
NSPoint ourpoint = [view convertPoint:windowpoint fromView:nil];
- EAffinity affinity;
- Position pos = [self topRenderer]->positionForCoordinates ((int)ourpoint.x, (int)ourpoint.y, &affinity);
- return (id) [self textMarkerForVisiblePosition:VisiblePosition(pos, affinity)];
+ VisiblePosition pos = [self topRenderer]->positionForCoordinates ((int)ourpoint.x, (int)ourpoint.y);
+ return (id) [self textMarkerForVisiblePosition:pos];
}
- (id)doAXBoundsForTextMarkerRange: (AXTextMarkerRangeRef) textMarkerRange
if (prevVisiblePos.isNull())
return nil;
- VisiblePosition startPosition = startOfLine(prevVisiblePos, prevVisiblePos.affinity());
- VisiblePosition endPosition = endOfLine(prevVisiblePos, prevVisiblePos.affinity());
+ VisiblePosition startPosition = startOfLine(prevVisiblePos);
+ VisiblePosition endPosition = endOfLine(prevVisiblePos);
return (id) [self textMarkerRangeFromVisiblePositions:startPosition andEndPos:endPosition];
}
if (nextVisiblePos.isNull())
return nil;
- VisiblePosition startPosition = startOfLine(nextVisiblePos, nextVisiblePos.affinity());
- VisiblePosition endPosition = endOfLine(nextVisiblePos, nextVisiblePos.affinity());
+ VisiblePosition startPosition = startOfLine(nextVisiblePos);
+ VisiblePosition endPosition = endOfLine(nextVisiblePos);
return (id) [self textMarkerRangeFromVisiblePositions:startPosition andEndPos:endPosition];
}
if (nextVisiblePos.isNull())
return nil;
- VisiblePosition endPosition = endOfLine(nextVisiblePos, nextVisiblePos.affinity());
+ VisiblePosition endPosition = endOfLine(nextVisiblePos);
return (id) [self textMarkerForVisiblePosition: endPosition];
}
if (prevVisiblePos.isNull())
return nil;
- VisiblePosition startPosition = startOfLine(prevVisiblePos, prevVisiblePos.affinity());
+ VisiblePosition startPosition = startOfLine(prevVisiblePos);
return (id) [self textMarkerForVisiblePosition: startPosition];
}
using khtml::StyleDashboardRegion;
using khtml::TextIterator;
using khtml::DOWNSTREAM;
-using khtml::UPSTREAM;
using khtml::VISIBLE;
using khtml::VisiblePosition;
using khtml::WordAwareIterator;
if (!node->renderer())
return VisiblePosition();
- EAffinity affinity;
- Position pos = node->renderer()->positionForCoordinates((int)point.x, (int)point.y, &affinity);
- return VisiblePosition(pos, affinity);
+ return node->renderer()->positionForCoordinates((int)point.x, (int)point.y);
}
- (void)moveDragCaretToPoint:(NSPoint)point