Reviewed by Dave.
WebCore part of fix for:
<rdar://problem/
3759187> REGRESSION (Mail): implement firstRectForCharacterRange:
* kwq/WebCoreBridge.h:
* kwq/WebCoreBridge.mm:
(-[WebCoreBridge firstRectForDOMRange:]): New method to compute the rect for a
DOMRange, or if the range is split into multiple lines, the rect for the part on
the first line only.
* khtml/rendering/render_object.cpp:
(RenderObject::caretRect): Added extraWidthToEndOfLine parameter and ditto
for the overrides below.
* khtml/rendering/render_object.h:
* khtml/rendering/render_box.cpp:
(RenderBox::caretRect):
* khtml/rendering/render_box.h:
* khtml/rendering/render_br.cpp:
(RenderBR::caretRect):
* khtml/rendering/render_br.h:
* khtml/rendering/render_flow.cpp:
(RenderFlow::caretRect):
* khtml/rendering/render_flow.h:
* khtml/rendering/render_text.cpp:
(RenderText::caretRect):
WebKit:
Reviewed by Dave.
WebKit part of fix for:
<rdar://problem/
3759187> REGRESSION (Mail): implement firstRectForCharacterRange:
* WebView.subproj/WebHTMLView.m:
(-[WebHTMLView firstRectForCharacterRange:]): Call the appropriate new bridge method,
and translate to screen coordinates.
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@7500
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
+2004-09-08 Maciej Stachowiak <mjs@apple.com>
+
+ Reviewed by Dave.
+
+ WebCore part of fix for:
+
+ <rdar://problem/3759187> REGRESSION (Mail): implement firstRectForCharacterRange:
+
+ * kwq/WebCoreBridge.h:
+ * kwq/WebCoreBridge.mm:
+ (-[WebCoreBridge firstRectForDOMRange:]): New method to compute the rect for a
+ DOMRange, or if the range is split into multiple lines, the rect for the part on
+ the first line only.
+
+ * khtml/rendering/render_object.cpp:
+ (RenderObject::caretRect): Added extraWidthToEndOfLine parameter and ditto
+ for the overrides below.
+ * khtml/rendering/render_object.h:
+ * khtml/rendering/render_box.cpp:
+ (RenderBox::caretRect):
+ * khtml/rendering/render_box.h:
+ * khtml/rendering/render_br.cpp:
+ (RenderBR::caretRect):
+ * khtml/rendering/render_br.h:
+ * khtml/rendering/render_flow.cpp:
+ (RenderFlow::caretRect):
+ * khtml/rendering/render_flow.h:
+ * khtml/rendering/render_text.cpp:
+ (RenderText::caretRect):
+
2004-09-06 Darin Adler <darin@apple.com>
Reviewed by Ken.
}
-QRect RenderBox::caretRect(int offset, bool override)
+QRect RenderBox::caretRect(int offset, bool override, int *extraWidthToEndOfLine)
{
// FIXME: Is it OK to check only first child instead of picking
// right child based on offset? Is it OK to pass the same offset
// propagate it downwards to its children, someone will feel responsible
RenderObject *child = firstChild();
if (child) {
- QRect result = child->caretRect(offset, override);
+ QRect result = child->caretRect(offset, override, extraWidthToEndOfLine);
// FIXME: in-band signalling!
if (result.x() != -1)
return result;
_x = _y = -1;
}
+ if (extraWidthToEndOfLine)
+ *extraWidthToEndOfLine = m_width - width;
+
return QRect(_x, _y, width, height);
}
virtual RenderLayer* layer() const { return m_layer; }
- virtual QRect caretRect(int offset, bool override);
+ virtual QRect caretRect(int offset, bool override, int *extraWidthToEndOfLine = 0);
virtual void paintBackgroundExtended(QPainter *p, const QColor &c, CachedImage *bg, int clipy, int cliph,
int _tx, int _ty, int w, int height,
return Position(element(), 0);
}
-QRect RenderBR::caretRect(int offset, bool override)
+QRect RenderBR::caretRect(int offset, bool override, int *extraWidthToEndOfLine)
{
// EDIT FIXME: This does not work yet. Some other changes are need before
// an accurate position can be determined.
+ if (extraWidthToEndOfLine)
+ *extraWidthToEndOfLine = containingBlockWidth();
+
int absx, absy;
absolutePosition(absx,absy);
virtual unsigned long caretMaxRenderedOffset() const;
virtual DOM::Position positionForCoordinates(int _x, int _y);
- virtual QRect caretRect(int offset, bool override);
+ virtual QRect caretRect(int offset, bool override, int *extraWidthToEndOfLine = 0);
virtual InlineBox *inlineBox(long offset);
return left;
}
-QRect RenderFlow::caretRect(int offset, bool override)
+QRect RenderFlow::caretRect(int offset, bool override, int *extraWidthToEndOfLine)
{
if (firstChild() || style()->display() == INLINE) {
// Do the normal calculation
- return RenderContainer::caretRect(offset, override);
+ return RenderContainer::caretRect(offset, override, extraWidthToEndOfLine);
}
// This is a special case:
}
_y = 0;
+
+ if (extraWidthToEndOfLine) {
+ if (isRenderBlock()) {
+ *extraWidthToEndOfLine = this->width() - (_x + width);
+ } else {
+ int myRight = _x + width;
+ int ignore;
+ absolutePosition(myRight, ignore);
+
+ int containerRight = containingBlock()->xPos() + containingBlockWidth();
+ absolutePosition(containerRight, ignore);
+
+ *extraWidthToEndOfLine = containerRight - myRight;
+ }
+ }
int absx, absy;
absolutePosition(absx, absy, false);
virtual int rightmostPosition(bool includeOverflowInterior=true, bool includeSelf=true) const;
virtual int leftmostPosition(bool includeOverflowInterior=true, bool includeSelf=true) const;
- virtual QRect caretRect(int offset, bool override);
+ virtual QRect caretRect(int offset, bool override, int *extraWidthToEndOfLine = 0);
protected:
// An inline can be split with blocks occurring in between the inline content.
}
}
-QRect RenderObject::caretRect(int /*offset*/, bool /*override*/)
+QRect RenderObject::caretRect(int /*offset*/, bool /*override*/, int *extraWidthToEndOfLine)
{
+ if (extraWidthToEndOfLine)
+ *extraWidthToEndOfLine = 0;
+
// the caret has a default width of one pixel. If you want
// to check for validity, only test the x-coordinate for >= 0.
return QRect(-1, -1, 1, -1);
* @param offset zero-based offset determining position within the render object.
* @param override @p true if input overrides existing characters,
* @p false if it inserts them. The width of the caret depends on this one.
+ * @param extraWidthToEndOfLine optional out arg to give extra width to end of line -
+ * useful for character range rect computations
*/
- virtual QRect caretRect(int offset, bool override);
+ virtual QRect caretRect(int offset, bool override, int *extraWidthToEndOfLine = 0);
virtual int lowestPosition(bool includeOverflowInterior=true, bool includeSelf=true) const { return 0; }
virtual int rightmostPosition(bool includeOverflowInterior=true, bool includeSelf=true) const { return 0; }
return Position(element(), 0);
}
-QRect RenderText::caretRect(int offset, bool override)
+QRect RenderText::caretRect(int offset, bool override, int *extraWidthToEndOfLine)
{
if (!firstTextBox() || stringLength() == 0) {
return QRect(-1, -1, 1, -1);
_x += fm.rightBearing(*(str->s + box->m_start + offset));
#endif
+ // FIXME: should we use the width of the root inline box or the
+ // width of the containing block for this?
+ if (extraWidthToEndOfLine)
+ *extraWidthToEndOfLine = (box->root()->width() + box->root()->xPos()) - (_x + 1);
+
int absx, absy;
absolutePosition(absx,absy);
_x += absx;
virtual SelectionState selectionState() const {return m_selectionState;}
virtual void setSelectionState(SelectionState s) {m_selectionState = s; }
- virtual QRect caretRect(int offset, bool override);
+ virtual QRect caretRect(int offset, bool override, int *extraWidthToEndOfLine = 0);
void posOfChar(int ch, int &x, int &y);
virtual short marginLeft() const { return style()->marginLeft().minWidth(0); }
- (NSRect)visibleSelectionRect;
- (NSImage *)selectionImage;
- (NSRect)caretRectAtNode:(DOMNode *)node offset:(int)offset;
+- (NSRect)firstRectForDOMRange:(DOMRange *)range;
- (void)setSelectedDOMRange:(DOMRange *)range affinity:(NSSelectionAffinity)selectionAffinity;
- (DOMRange *)selectedDOMRange;
return [node _nodeImpl]->renderer()->caretRect(offset, true);
}
+- (NSRect)firstRectForDOMRange:(DOMRange *)range
+{
+ int extraWidthToEndOfLine = 0;
+ QRect startCaretRect = [[range startContainer] _nodeImpl]->renderer()->caretRect([range startOffset], true, &extraWidthToEndOfLine);
+ QRect endCaretRect = [[range startContainer] _nodeImpl]->renderer()->caretRect([range endOffset], true);
+
+ if (startCaretRect.y() == endCaretRect.y()) {
+ // start and end are on the same line
+ return QRect(MIN(startCaretRect.x(), endCaretRect.x()),
+ startCaretRect.y(),
+ abs(endCaretRect.x() - startCaretRect.x()),
+ MAX(startCaretRect.height(), endCaretRect.height()));
+ }
+
+ // start and end aren't on the same line, so go from start to the end of its line
+ return QRect(startCaretRect.x(),
+ startCaretRect.y(),
+ startCaretRect.width() + extraWidthToEndOfLine,
+ startCaretRect.height());
+}
+
+
- (NSImage *)selectionImage
{
return _part->selectionImage();
+2004-09-08 Maciej Stachowiak <mjs@apple.com>
+
+ Reviewed by Dave.
+
+ WebKit part of fix for:
+
+ <rdar://problem/3759187> REGRESSION (Mail): implement firstRectForCharacterRange:
+
+ * WebView.subproj/WebHTMLView.m:
+ (-[WebHTMLView firstRectForCharacterRange:]): Call the appropriate new bridge method,
+ and translate to screen coordinates.
+
2004-09-09 Darin Adler <darin@apple.com>
Reviewed by Ken.
- (NSRect)firstRectForCharacterRange:(NSRange)theRange
{
- ERROR("TEXTINPUT: firstRectForCharacterRange: not yet implemented");
- return NSMakeRect(0,0,0,0);
+ NSLog(@"location: %d length: %d\n", theRange.location, theRange.length);
+
+ if (![self hasMarkedText]) {
+ return NSMakeRect(0,0,0,0);
+ }
+
+ WebBridge *bridge = [self _bridge];
+
+ DOMRange *rectRange = [[bridge DOMDocument] createRange];
+ DOMRange *markedRange = [bridge markedDOMRange];
+ [rectRange setStart:[markedRange startContainer] :theRange.location];
+ [rectRange setEnd:[markedRange startContainer] :(theRange.location + theRange.length)];
+
+ NSRect resultRect = [self convertRect:[bridge firstRectForDOMRange:rectRange] toView:nil];
+ resultRect.origin = [[self window] convertBaseToScreen:resultRect.origin];
+
+ NSLog(@"(%d,%d) %dx%d\n", (int)resultRect.origin.x, (int)resultRect.origin.y, (int)resultRect.size.width, (int)resultRect.size.height);
+
+ return resultRect;
}
- (NSRange)selectedRange