Changeset 13028 in webkit
- Timestamp:
- Feb 27, 2006 4:41:39 PM (18 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r13022 r13028 1 2006-02-27 Justin Garcia <justin.garcia@apple.com> 2 3 Reviewed by darin 4 5 Test for: 6 <http://bugzilla.opendarwin.org/show_bug.cgi?id=6844> 7 elementAtPoint returns the list when the point is over a list marker 8 9 * fast/events/onclick-list-marker-expected.txt: Added. 10 * fast/events/onclick-list-marker.html: Added. 11 1 12 2006-02-25 Eric Seidel <eseidel@apple.com> 2 13 -
trunk/WebCore/ChangeLog
r13027 r13028 1 2006-02-27 Justin Garcia <justin.garcia@apple.com> 2 3 Reviewed by darin 4 5 <http://bugzilla.opendarwin.org/show_bug.cgi?id=6844> 6 elementAtPoint returns the list when the point is over a list marker 7 8 Consider the case of outside list markers in nodeAtPoint. Had to pull 9 the code out of RenderListMarker::paint that computed the position/size 10 of the list marker. 11 12 Added: 13 * fast/events/onclick-list-marker.html 14 15 * rendering/render_list.cpp: 16 (RenderListItem::nodeAtPoint): 17 (RenderListItem::getAbsoluteRepaintRect): 18 (RenderListMarker::paint): 19 (RenderListMarker::nodeAtPoint): 20 (RenderListMarker::getRelativeMarkerRect): 21 * rendering/render_list.h: 22 * rendering/render_object.h: 23 1 24 2006-02-27 Eric Seidel <eseidel@apple.com> 2 25 -
trunk/WebCore/rendering/render_list.cpp
r12977 r13028 289 289 } 290 290 291 // We need to override RenderBlock::nodeAtPoint so that a point over an outside list marker will return the list item. 292 // We should remove this when we improve the way list markers are stored in the render tree. 293 bool RenderListItem::nodeAtPoint(NodeInfo& i, int x, int y, int tx, int ty, HitTestAction hitTestAction) 294 { 295 if (RenderBlock::nodeAtPoint(i, x, y, tx, ty, hitTestAction)) 296 return true; 297 298 if (!m_marker || m_marker->isInside() || hitTestAction != HitTestForeground) 299 return false; 300 301 return m_marker->nodeAtPoint(i, x, y, tx + m_x, ty + m_y, hitTestAction); 302 } 303 291 304 void RenderListItem::calcMinMaxWidth() 292 305 { … … 317 330 { 318 331 IntRect result = RenderBlock::getAbsoluteRepaintRect(); 319 if (m_marker && !m_marker->isInside()) { 320 // This can be a sloppy and imprecise offset as long as it's always too big. 321 int pixHeight = style()->fontDescription().computedPixelSize(); 322 int offset = pixHeight*2/3; 323 bool haveImage = m_marker->listImage() && !m_marker->listImage()->isErrorImage(); 324 if (haveImage) 325 offset = m_marker->listImage()->image()->width(); 326 int bulletWidth = offset/2; 327 if (offset%2) 328 bulletWidth++; 329 int xoff = 0; 330 if (style()->direction() == LTR) 331 xoff = -cMarkerPadding - offset; 332 else 333 xoff = cMarkerPadding + (haveImage ? 0 : (offset - bulletWidth)); 334 335 if (xoff < 0) { 336 result.setX(result.x() + xoff); 337 result.setWidth(result.width() - xoff); 338 } else 339 result.setWidth(result.width() + xoff); 332 if (m_marker && m_marker->parent() == this && !m_marker->isInside()) { 333 IntRect markerRect = m_marker->getRelativeMarkerRect(); 334 int x, y; 335 absolutePosition(x, y); 336 markerRect.move(x, y); 337 result.unite(markerRect); 340 338 } 341 339 return result; … … 389 387 if (style()->visibility() != VISIBLE) return; 390 388 391 _tx += m_x; 392 _ty += m_y; 393 394 if (_ty > i.r.bottom() || _ty + m_height < i.r.y()) 389 IntRect marker = getRelativeMarkerRect(); 390 marker.move(IntPoint(_tx, _ty)); 391 392 IntRect box(_tx + m_x, _ty + m_y, m_height, m_width); 393 394 if (box.y() > i.r.bottom() || box.y() + box.height() < i.r.y()) 395 395 return; 396 396 397 397 if (shouldPaintBackgroundOrBorder()) 398 paintBoxDecorations(i, _tx, _ty);398 paintBoxDecorations(i, box.x(), box.y()); 399 399 400 400 QPainter* p = i.p; 401 401 p->setFont(style()->qfont()); 402 402 const QFontMetrics fm = p->fontMetrics(); 403 404 // The marker needs to adjust its tx, for the case where it's an outside marker.405 RenderObject* listItem = 0;406 int leftLineOffset = 0;407 int rightLineOffset = 0;408 if (!isInside()) {409 listItem = this;410 int yOffset = 0;411 int xOffset = 0;412 while (listItem && listItem != m_listItem) {413 yOffset += listItem->yPos();414 xOffset += listItem->xPos();415 listItem = listItem->parent();416 }417 418 // Now that we have our xoffset within the listbox, we need to adjust ourselves by the delta419 // between our current xoffset and our desired position (which is just outside the border box420 // of the list item).421 if (style()->direction() == LTR) {422 leftLineOffset = m_listItem->leftRelOffset(yOffset, m_listItem->leftOffset(yOffset));423 _tx -= (xOffset - leftLineOffset) + m_listItem->paddingLeft() + m_listItem->borderLeft();424 } else {425 rightLineOffset = m_listItem->rightRelOffset(yOffset, m_listItem->rightOffset(yOffset));426 _tx += (rightLineOffset-xOffset) + m_listItem->paddingRight() + m_listItem->borderRight();427 }428 }429 403 430 404 if (p->printing()) { 431 if ( _ty< i.r.y())405 if (box.y() < i.r.y()) 432 406 // This has been printed already we suppose. 433 407 return; 434 408 435 409 RenderCanvas* c = canvas(); 436 if ( _ty + m_height+ paddingBottom() + borderBottom() >= c->printRect().bottom()) {437 if ( _ty< c->truncatedAt())438 c->setBestTruncatedAt( _ty, this);410 if (box.y() + box.height() + paddingBottom() + borderBottom() >= c->printRect().bottom()) { 411 if (box.y() < c->truncatedAt()) 412 c->setBestTruncatedAt(box.y(), this); 439 413 // Let's print this on the next page. 440 414 return; 441 415 } 442 416 } 443 444 int offset = fm.ascent()*2/3; 445 bool haveImage = m_listImage && !m_listImage->isErrorImage(); 446 if (haveImage) 447 offset = m_listImage->image()->width(); 448 449 int xoff = 0; 450 int yoff = fm.ascent() - offset; 451 452 int bulletWidth = offset/2; 453 if (offset%2) 454 bulletWidth++; 455 if (!isInside()) { 456 if (listItem->style()->direction() == LTR) 457 xoff = -cMarkerPadding - offset; 458 else 459 xoff = cMarkerPadding + (haveImage ? 0 : (offset - bulletWidth)); 460 } else if (style()->direction() == RTL) 461 xoff += haveImage ? cMarkerPadding : (m_width - bulletWidth); 462 417 463 418 if (m_listImage && !m_listImage->isErrorImage()) { 464 p->drawImageAtPoint(m_listImage->image(), IntPoint(_tx + xoff, _ty));419 p->drawImageAtPoint(m_listImage->image(), marker.location()); 465 420 return; 466 421 } … … 468 423 #ifdef BOX_DEBUG 469 424 p->setPen( Qt::red ); 470 p->drawRect( _tx + xoff, _ty + yoff, offset, offset);425 p->drawRect(box.x(), box.y(), box.width(), box.height()); 471 426 #endif 472 427 … … 477 432 case DISC: 478 433 p->setBrush(color); 479 p->drawEllipse( _tx + xoff, _ty + (3 * yoff)/2, bulletWidth, bulletWidth);434 p->drawEllipse(marker.x(), marker.y(), marker.width(), marker.height()); 480 435 return; 481 436 case CIRCLE: 482 437 p->setBrush(WebCore::Brush::NoBrush); 483 p->drawEllipse( _tx + xoff, _ty + (3 * yoff)/2, bulletWidth, bulletWidth);438 p->drawEllipse(marker.x(), marker.y(), marker.width(), marker.height()); 484 439 return; 485 440 case SQUARE: 486 441 p->setBrush(color); 487 p->drawRect( _tx + xoff, _ty + (3 * yoff)/2, bulletWidth, bulletWidth);442 p->drawRect(marker.x(), marker.y(), marker.width(), marker.height()); 488 443 return; 489 444 case LNONE: … … 491 446 default: 492 447 if (!m_item.isEmpty()) { 493 _ty += fm.ascent();494 495 448 if (isInside()) { 496 449 if( style()->direction() == LTR) { 497 p->drawText( _tx, _ty, 0, 0, 0, 0, Qt::AlignLeft, m_item);498 p->drawText( _tx + fm.width(m_item, 0, 0), _ty, 0, 0, 0, 0, Qt::AlignLeft, ". ");450 p->drawText(marker.x(), marker.y(), 0, 0, 0, 0, Qt::AlignLeft, m_item); 451 p->drawText(marker.x() + fm.width(m_item, 0, 0), marker.y(), 0, 0, 0, 0, Qt::AlignLeft, ". "); 499 452 } else { 500 p->drawText( _tx, _ty, 0, 0, 0, 0, Qt::AlignLeft, " .");501 p->drawText( _tx + fm.width(" .", 0, 0), _ty, 0, 0, 0, 0, Qt::AlignLeft, m_item);453 p->drawText(marker.x(), marker.y(), 0, 0, 0, 0, Qt::AlignLeft, " ."); 454 p->drawText(marker.x() + fm.width(" .", 0, 0), marker.y(), 0, 0, 0, 0, Qt::AlignLeft, m_item); 502 455 } 503 456 } else { 504 457 if (style()->direction() == LTR) { 505 p->drawText( _tx - offset/2, _ty, 0, 0, 0, 0, Qt::AlignRight, ". ");506 p->drawText( _tx - offset/2 - fm.width(". ", 0, 0), _ty, 0, 0, 0, 0, Qt::AlignRight, m_item);458 p->drawText(marker.x(), marker.y(), 0, 0, 0, 0, Qt::AlignRight, ". "); 459 p->drawText(marker.x() - fm.width(". ", 0, 0), marker.y(), 0, 0, 0, 0, Qt::AlignRight, m_item); 507 460 } else { 508 p->drawText( _tx + offset / 2, _ty, 0, 0, 0, 0, Qt::AlignLeft, " .");509 p->drawText( _tx + offset / 2 + fm.width(" .", 0, 0), _ty, 0, 0, 0, 0, Qt::AlignLeft, m_item);461 p->drawText(marker.x(), marker.y(), 0, 0, 0, 0, Qt::AlignLeft, " ."); 462 p->drawText(marker.x() + fm.width(" .", 0, 0), marker.y(), 0, 0, 0, 0, Qt::AlignLeft, m_item); 510 463 } 511 464 } … … 649 602 } 650 603 604 bool RenderListMarker::nodeAtPoint(NodeInfo& i, int x, int y, int tx, int ty, HitTestAction hitTestAction) 605 { 606 IntRect markerRect = getRelativeMarkerRect(); 607 markerRect.move(tx, ty); 608 if (!markerRect.contains(x, y)) 609 return false; 610 611 i.setInnerNode(m_listItem->element()); 612 return true; 613 } 614 615 IntRect RenderListMarker::getRelativeMarkerRect() 616 { 617 int x = m_x; 618 int y = m_y; 619 620 RenderObject* listItem = 0; 621 int leftLineOffset = 0; 622 int rightLineOffset = 0; 623 if (!isInside()) { 624 listItem = this; 625 int yOffset = 0; 626 int xOffset = 0; 627 while (listItem && listItem != m_listItem) { 628 yOffset += listItem->yPos(); 629 xOffset += listItem->xPos(); 630 listItem = listItem->parent(); 631 } 632 633 // Now that we have our xoffset within the listbox, we need to adjust ourselves by the delta 634 // between our current xoffset and our desired position (which is just outside the border box 635 // of the list item). 636 if (style()->direction() == LTR) { 637 leftLineOffset = m_listItem->leftRelOffset(yOffset, m_listItem->leftOffset(yOffset)); 638 x -= (xOffset - leftLineOffset) + m_listItem->paddingLeft() + m_listItem->borderLeft(); 639 } else { 640 rightLineOffset = m_listItem->rightRelOffset(yOffset, m_listItem->rightOffset(yOffset)); 641 x += (rightLineOffset-xOffset) + m_listItem->paddingRight() + m_listItem->borderRight(); 642 } 643 } 644 645 const QFontMetrics fm = style() ? style()->fontMetrics() : QFontMetrics(); 646 647 int offset = fm.ascent()*2/3; 648 bool haveImage = m_listImage && !m_listImage->isErrorImage(); 649 if (haveImage) 650 offset = m_listImage->image()->width(); 651 652 int xoff = 0; 653 int yoff = fm.ascent() - offset; 654 655 int bulletWidth = offset/2; 656 if (offset%2) 657 bulletWidth++; 658 if (!isInside()) { 659 if (listItem->style()->direction() == LTR) 660 xoff = -cMarkerPadding - offset; 661 else 662 xoff = cMarkerPadding + (haveImage ? 0 : (offset - bulletWidth)); 663 } else if (style()->direction() == RTL) 664 xoff += haveImage ? cMarkerPadding : (m_width - bulletWidth); 665 666 if (m_listImage && !m_listImage->isErrorImage()) 667 return IntRect(x + xoff, y, m_listImage->imageSize().width(), m_listImage->imageSize().height()); 668 669 switch(style()->listStyleType()) { 670 case DISC: 671 case CIRCLE: 672 case SQUARE: 673 return IntRect(x + xoff, y + (3 * yoff)/2, bulletWidth, bulletWidth); 674 case LNONE: 675 return IntRect(); 676 default: 677 if (m_item.isEmpty()) 678 return IntRect(); 679 680 y += fm.ascent(); 681 682 if (isInside()) 683 return IntRect(x, y, fm.width(m_item, 0, 0) + fm.width(". ", 0, 0), fm.height()); 684 else { 685 if (style()->direction() == LTR) 686 return IntRect(x - offset / 2, y, fm.width(m_item, 0, 0) + fm.width(". ", 0, 0), fm.height()); 687 else 688 return IntRect(x + offset / 2, y, fm.width(m_item, 0, 0) + fm.width(". ", 0, 0), fm.height()); 689 } 690 } 691 } 692 651 693 #undef BOX_DEBUG -
trunk/WebCore/rendering/render_list.h
r12560 r13028 71 71 72 72 bool isInside() const; 73 73 74 virtual bool nodeAtPoint(NodeInfo&, int, int, int, int, HitTestAction); 75 76 IntRect getRelativeMarkerRect(); 77 74 78 private: 75 79 QString m_item; … … 117 121 118 122 QString markerStringValue() { return m_marker ? m_marker->text() : ""; } 123 124 virtual bool nodeAtPoint(NodeInfo&, int, int, int, int, HitTestAction); 119 125 120 126 private: -
trunk/WebCore/rendering/render_object.h
r12977 r13028 495 495 bool active() const { return m_active; } 496 496 bool mouseMove() const { return m_mouseMove; } 497 498 private: 497 499 498 void setInnerNode(DOM::NodeImpl* n) { m_innerNode = n; } 500 499 void setInnerNonSharedNode(DOM::NodeImpl* n) { m_innerNonSharedNode = n; } 501 500 void setURLElement(DOM::NodeImpl* n) { m_innerURLElement = n; } 502 501 502 private: 503 503 DOM::NodeImpl* m_innerNode; 504 504 DOM::NodeImpl* m_innerNonSharedNode;
Note: See TracChangeset
for help on using the changeset viewer.